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.

273 lines
9.0 KiB

7 years ago
7 years ago
7 years ago
5 years ago
7 years ago
5 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
7 years ago
5 years ago
5 years ago
7 years ago
5 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
7 years ago
5 years ago
5 years ago
7 years ago
5 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::{Action, Symbol, SymbolRunner};
  5. pub struct List<'a> {
  6. symbols: Vec<Box<dyn Symbol + 'a>>,
  7. }
  8. impl<'a> List<'a> {
  9. pub fn new(symbols: Vec<Box<dyn Symbol + 'a>>) -> Self {
  10. List { symbols }
  11. }
  12. }
  13. impl<'a> Symbol for List<'a> {
  14. fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
  15. for symbol in &self.symbols {
  16. if !symbol.target_reached()? {
  17. return Ok(false);
  18. }
  19. }
  20. Ok(true)
  21. }
  22. fn execute(&self) -> Result<(), Box<dyn Error>> {
  23. for symbol in &self.symbols {
  24. symbol.execute()?;
  25. }
  26. Ok(())
  27. }
  28. fn get_prerequisites(&self) -> Vec<Resource> {
  29. let mut r = vec![];
  30. for symbol in &self.symbols {
  31. for req in symbol.get_prerequisites() {
  32. if self.provides().map_or(true, |p| !p.contains(&req)) {
  33. r.push(req)
  34. }
  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.is_empty() {
  47. None
  48. } else {
  49. Some(r)
  50. }
  51. }
  52. fn as_action<'b>(&'b self, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b> {
  53. Box::new(SymbolListAction::new(runner, &self.symbols))
  54. }
  55. fn into_action<'b>(self: Box<Self>, runner: &'b dyn SymbolRunner) -> Box<dyn Action + 'b>
  56. where
  57. Self: 'b,
  58. {
  59. Box::new(ListAction::new(
  60. self
  61. .symbols
  62. .into_iter()
  63. .map(|s| s.into_action(runner))
  64. .collect(),
  65. ))
  66. }
  67. }
  68. impl<'a, A: 'a + Symbol, B: 'a + Symbol> From<(A, B)> for List<'a> {
  69. fn from((a, b): (A, B)) -> Self {
  70. Self::new(vec![Box::new(a), Box::new(b)])
  71. }
  72. }
  73. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol> From<(A, B, C)> for List<'a> {
  74. fn from((a, b, c): (A, B, C)) -> Self {
  75. Self::new(vec![Box::new(a), Box::new(b), Box::new(c)])
  76. }
  77. }
  78. #[rustfmt::skip]
  79. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol> From<(A, B, C, D)> for List<'a> {
  80. fn from((a, b, c, d): (A, B, C, D)) -> Self {
  81. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d)])
  82. }
  83. }
  84. #[rustfmt::skip]
  85. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol> From<(A, B, C, D, E)> for List<'a> {
  86. fn from((a, b, c, d, e): (A, B, C, D, E)) -> Self {
  87. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e)])
  88. }
  89. }
  90. #[rustfmt::skip]
  91. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol, F: 'a + Symbol> From<(A, B, C, D, E, F)> for List<'a> {
  92. fn from((a, b, c, d, e, f): (A, B, C, D, E, F)) -> Self {
  93. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e), Box::new(f)])
  94. }
  95. }
  96. #[rustfmt::skip]
  97. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol, F: 'a + Symbol, G: 'a + Symbol> From<(A, B, C, D, E, F, G)> for List<'a> {
  98. fn from((a, b, c, d, e, f, g): (A, B, C, D, E, F, G)) -> Self {
  99. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e), Box::new(f), Box::new(g)])
  100. }
  101. }
  102. #[rustfmt::skip]
  103. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol, F: 'a + Symbol, G: 'a + Symbol, H: 'a + Symbol> From<(A, B, C, D, E, F, G, H)> for List<'a> {
  104. fn from((a, b, c, d, e, f, g, h): (A, B, C, D, E, F, G, H)) -> Self {
  105. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e), Box::new(f), Box::new(g), Box::new(h)])
  106. }
  107. }
  108. #[rustfmt::skip]
  109. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol, F: 'a + Symbol, G: 'a + Symbol, H: 'a + Symbol, I: 'a + Symbol, J: 'a + Symbol, K: 'a + Symbol> From<(A, B, C, D, E, F, G, H, I, J, K)> for List<'a> {
  110. fn from((a, b, c, d, e, f, g, h, i, j, k): (A, B, C, D, E, F, G, H, I, J, K)) -> Self {
  111. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e), Box::new(f), Box::new(g), Box::new(h), Box::new(i), Box::new(j), Box::new(k)])
  112. }
  113. }
  114. #[rustfmt::skip]
  115. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol, F: 'a + Symbol, G: 'a + Symbol, H: 'a + Symbol, I: 'a + Symbol, J: 'a + Symbol, K: 'a + Symbol, L: 'a + Symbol> From<(A, B, C, D, E, F, G, H, I, J, K, L)> for List<'a> {
  116. fn from((a, b, c, d, e, f, g, h, i, j, k, l): (A, B, C, D, E, F, G, H, I, J, K, L)) -> Self {
  117. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e), Box::new(f), Box::new(g), Box::new(h), Box::new(i), Box::new(j), Box::new(k), Box::new(l)])
  118. }
  119. }
  120. #[rustfmt::skip]
  121. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol, F: 'a + Symbol, G: 'a + Symbol, H: 'a + Symbol, I: 'a + Symbol, J: 'a + Symbol, K: 'a + Symbol, L: 'a + Symbol, M: 'a + Symbol> From<(A, B, C, D, E, F, G, H, I, J, K, L, M)> for List<'a> {
  122. fn from((a, b, c, d, e, f, g, h, i, j, k, l, m): (A, B, C, D, E, F, G, H, I, J, K, L, M)) -> Self {
  123. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e), Box::new(f), Box::new(g), Box::new(h), Box::new(i), Box::new(j), Box::new(k), Box::new(l), Box::new(m)])
  124. }
  125. }
  126. #[rustfmt::skip]
  127. impl<'a, A: 'a + Symbol, B: 'a + Symbol, C: 'a + Symbol, D: 'a + Symbol, E: 'a + Symbol, F: 'a + Symbol, G: 'a + Symbol, H: 'a + Symbol, I: 'a + Symbol, J: 'a + Symbol, K: 'a + Symbol, L: 'a + Symbol, M: 'a + Symbol, N: 'a + Symbol> From<(A, B, C, D, E, F, G, H, I, J, K, L, M, N)> for List<'a> {
  128. fn from((a, b, c, d, e, f, g, h, i, j, k, l, m, n): (A, B, C, D, E, F, G, H, I, J, K, L, M, N)) -> Self {
  129. Self::new(vec![Box::new(a), Box::new(b), Box::new(c), Box::new(d), Box::new(e), Box::new(f), Box::new(g), Box::new(h), Box::new(i), Box::new(j), Box::new(k), Box::new(l), Box::new(m), Box::new(n)])
  130. }
  131. }
  132. struct SymbolListAction<'a> {
  133. runner: &'a dyn SymbolRunner,
  134. symbols: &'a [Box<dyn Symbol + 'a>],
  135. }
  136. impl<'a> SymbolListAction<'a> {
  137. fn new(runner: &'a dyn SymbolRunner, symbols: &'a [Box<dyn Symbol + 'a>]) -> Self {
  138. Self { runner, symbols }
  139. }
  140. }
  141. impl<'a> Action for SymbolListAction<'a> {
  142. fn run(&self) -> Result<(), Box<dyn Error>> {
  143. for symbol in self.symbols {
  144. symbol.as_action(self.runner).run()?;
  145. }
  146. Ok(())
  147. }
  148. }
  149. pub struct ListAction<'a> {
  150. actions: Vec<Box<dyn Action + 'a>>,
  151. }
  152. impl<'a> ListAction<'a> {
  153. pub fn new(actions: Vec<Box<dyn Action + 'a>>) -> Self {
  154. Self { actions }
  155. }
  156. }
  157. impl<'a> Action for ListAction<'a> {
  158. fn run(&self) -> Result<(), Box<dyn Error>> {
  159. for action in &self.actions {
  160. action.run()?;
  161. }
  162. Ok(())
  163. }
  164. }
  165. impl<'a> fmt::Display for List<'a> {
  166. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  167. write!(f, "List [ ")?;
  168. for symbol in &self.symbols {
  169. write!(f, "{} ", symbol)?;
  170. }
  171. write!(f, "]")
  172. }
  173. }
  174. /*
  175. #[cfg(test)]
  176. mod test {
  177. use std::error::Error;
  178. use std::fmt;
  179. use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
  180. use symbols::hook::List;
  181. struct ErrSymbol(String);
  182. impl Symbol for ErrSymbol {
  183. fn target_reached(&self) -> Result<bool, Box<Error>> { Err(self.0.clone().into()) }
  184. fn execute(&self) -> Result<(), Box<Error>> { Err(self.0.clone().into()) }
  185. }
  186. impl fmt::Display for ErrSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } }
  187. struct OkSymbol(bool);
  188. impl Symbol for OkSymbol {
  189. fn target_reached(&self) -> Result<bool, Box<Error>> { Ok(self.0) }
  190. fn execute(&self) -> Result<(), Box<Error>> { Ok(()) }
  191. }
  192. impl fmt::Display for OkSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } }
  193. #[test]
  194. fn first_target_reached_fails() {
  195. let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).target_reached();
  196. assert_eq!(res.unwrap_err().description(), "first");
  197. }
  198. #[test]
  199. fn first_target_not_reached() {
  200. let res = List::new(OkSymbol(false), ErrSymbol("second".into())).target_reached();
  201. assert_eq!(res.unwrap(), false);
  202. }
  203. #[test]
  204. fn second_target_reached_fails() {
  205. let res = List::new(OkSymbol(true), ErrSymbol("second".into())).target_reached();
  206. assert_eq!(res.unwrap_err().description(), "second");
  207. }
  208. #[test]
  209. fn second_target_not_reached() {
  210. let res = List::new(OkSymbol(true), OkSymbol(false)).target_reached();
  211. assert_eq!(res.unwrap(), false);
  212. }
  213. #[test]
  214. fn everything_reached() {
  215. let res = List::new(OkSymbol(true), OkSymbol(true)).target_reached();
  216. assert_eq!(res.unwrap(), true);
  217. }
  218. #[test]
  219. fn first_execute_fails() {
  220. let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).execute();
  221. assert_eq!(res.unwrap_err().description(), "first");
  222. }
  223. #[test]
  224. fn second_execute_fails() {
  225. let res = List::new(OkSymbol(true), ErrSymbol("second".into())).execute();
  226. assert_eq!(res.unwrap_err().description(), "second");
  227. }
  228. #[test]
  229. fn everything_executes() {
  230. let res = List::new(OkSymbol(true), OkSymbol(true)).execute();
  231. assert_eq!(res.unwrap(), ());
  232. }
  233. }
  234. */