A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
3.5 KiB

7 years ago
7 years ago
7 years ago
7 years ago
  1. use std::error::Error;
  2. use std::fmt;
  3. use resources::Resource;
  4. use symbols::Symbol;
  5. pub struct List<'a> {
  6. symbols: Vec<Box<Symbol + 'a>>
  7. }
  8. impl<'a> List<'a> {
  9. pub fn new(symbols: Vec<Box<Symbol + 'a>>) -> Self {
  10. List { symbols: symbols }
  11. }
  12. }
  13. impl<'a> Symbol for List<'a> {
  14. fn target_reached(&self) -> Result<bool, Box<Error>> {
  15. for symbol in &self.symbols {
  16. match symbol.target_reached() {
  17. Ok(false) => return Ok(false),
  18. Err(e) => return Err(e),
  19. Ok(true) => {}
  20. }
  21. }
  22. Ok(true)
  23. }
  24. fn execute(&self) -> Result<(), Box<Error>> {
  25. for symbol in &self.symbols {
  26. try!(symbol.execute());
  27. }
  28. Ok(())
  29. }
  30. fn get_prerequisites(&self) -> Vec<Resource> {
  31. let mut r = vec![];
  32. for symbol in &self.symbols {
  33. for req in symbol.get_prerequisites() {
  34. if self.provides().map_or(true, |p| !p.contains(&req)) { r.push(req) }
  35. }
  36. }
  37. r
  38. }
  39. fn provides(&self) -> Option<Vec<Resource>> {
  40. let mut r = vec![];
  41. for symbol in &self.symbols {
  42. if let Some(provides) = symbol.provides() {
  43. r.extend(provides.into_iter());
  44. }
  45. }
  46. if r.len() > 0 { Some(r) } else { None }
  47. }
  48. }
  49. impl<'a> fmt::Display for List<'a> {
  50. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{
  51. try!(write!(f, "List [ "));
  52. for symbol in &self.symbols {
  53. try!(write!(f, "{} ", symbol));
  54. }
  55. write!(f, "]")
  56. }
  57. }
  58. /*
  59. #[cfg(test)]
  60. mod test {
  61. use std::error::Error;
  62. use std::fmt;
  63. use symbols::Symbol;
  64. use symbols::hook::List;
  65. struct ErrSymbol(String);
  66. impl Symbol for ErrSymbol {
  67. fn target_reached(&self) -> Result<bool, Box<Error>> { Err(self.0.clone().into()) }
  68. fn execute(&self) -> Result<(), Box<Error>> { Err(self.0.clone().into()) }
  69. }
  70. impl fmt::Display for ErrSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } }
  71. struct OkSymbol(bool);
  72. impl Symbol for OkSymbol {
  73. fn target_reached(&self) -> Result<bool, Box<Error>> { Ok(self.0) }
  74. fn execute(&self) -> Result<(), Box<Error>> { Ok(()) }
  75. }
  76. impl fmt::Display for OkSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } }
  77. #[test]
  78. fn first_target_reached_fails() {
  79. let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).target_reached();
  80. assert_eq!(res.unwrap_err().description(), "first");
  81. }
  82. #[test]
  83. fn first_target_not_reached() {
  84. let res = List::new(OkSymbol(false), ErrSymbol("second".into())).target_reached();
  85. assert_eq!(res.unwrap(), false);
  86. }
  87. #[test]
  88. fn second_target_reached_fails() {
  89. let res = List::new(OkSymbol(true), ErrSymbol("second".into())).target_reached();
  90. assert_eq!(res.unwrap_err().description(), "second");
  91. }
  92. #[test]
  93. fn second_target_not_reached() {
  94. let res = List::new(OkSymbol(true), OkSymbol(false)).target_reached();
  95. assert_eq!(res.unwrap(), false);
  96. }
  97. #[test]
  98. fn everything_reached() {
  99. let res = List::new(OkSymbol(true), OkSymbol(true)).target_reached();
  100. assert_eq!(res.unwrap(), true);
  101. }
  102. #[test]
  103. fn first_execute_fails() {
  104. let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).execute();
  105. assert_eq!(res.unwrap_err().description(), "first");
  106. }
  107. #[test]
  108. fn second_execute_fails() {
  109. let res = List::new(OkSymbol(true), ErrSymbol("second".into())).execute();
  110. assert_eq!(res.unwrap_err().description(), "second");
  111. }
  112. #[test]
  113. fn everything_executes() {
  114. let res = List::new(OkSymbol(true), OkSymbol(true)).execute();
  115. assert_eq!(res.unwrap(), ());
  116. }
  117. }
  118. */