use std::error::Error; use std::fmt; use resources::Resource; use symbols::Symbol; pub struct List<'a> { symbols: Vec> } impl<'a> List<'a> { pub fn new(symbols: Vec>) -> Self { List { symbols: symbols } } } impl<'a> Symbol for List<'a> { fn target_reached(&self) -> Result> { for symbol in &self.symbols { match symbol.target_reached() { Ok(false) => return Ok(false), Err(e) => return Err(e), Ok(true) => {} } } Ok(true) } fn execute(&self) -> Result<(), Box> { for symbol in &self.symbols { try!(symbol.execute()); } Ok(()) } fn get_prerequisites(&self) -> Vec { let mut r = vec![]; for symbol in &self.symbols { for req in symbol.get_prerequisites() { if self.provides().map_or(true, |p| !p.contains(&req)) { r.push(req) } } } r } fn provides(&self) -> Option> { let mut r = vec![]; for symbol in &self.symbols { if let Some(provides) = symbol.provides() { r.extend(provides.into_iter()); } } if r.len() > 0 { Some(r) } else { None } } } impl<'a> fmt::Display for List<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ try!(write!(f, "List [ ")); for symbol in &self.symbols { try!(write!(f, "{} ", symbol)); } write!(f, "]") } } /* #[cfg(test)] mod test { use std::error::Error; use std::fmt; use symbols::Symbol; use symbols::hook::List; struct ErrSymbol(String); impl Symbol for ErrSymbol { fn target_reached(&self) -> Result> { Err(self.0.clone().into()) } fn execute(&self) -> Result<(), Box> { Err(self.0.clone().into()) } } impl fmt::Display for ErrSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } } struct OkSymbol(bool); impl Symbol for OkSymbol { fn target_reached(&self) -> Result> { Ok(self.0) } fn execute(&self) -> Result<(), Box> { Ok(()) } } impl fmt::Display for OkSymbol { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{ write!(f, "") } } #[test] fn first_target_reached_fails() { let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).target_reached(); assert_eq!(res.unwrap_err().description(), "first"); } #[test] fn first_target_not_reached() { let res = List::new(OkSymbol(false), ErrSymbol("second".into())).target_reached(); assert_eq!(res.unwrap(), false); } #[test] fn second_target_reached_fails() { let res = List::new(OkSymbol(true), ErrSymbol("second".into())).target_reached(); assert_eq!(res.unwrap_err().description(), "second"); } #[test] fn second_target_not_reached() { let res = List::new(OkSymbol(true), OkSymbol(false)).target_reached(); assert_eq!(res.unwrap(), false); } #[test] fn everything_reached() { let res = List::new(OkSymbol(true), OkSymbol(true)).target_reached(); assert_eq!(res.unwrap(), true); } #[test] fn first_execute_fails() { let res = List::new(ErrSymbol("first".into()), ErrSymbol("second".into())).execute(); assert_eq!(res.unwrap_err().description(), "first"); } #[test] fn second_execute_fails() { let res = List::new(OkSymbol(true), ErrSymbol("second".into())).execute(); assert_eq!(res.unwrap_err().description(), "second"); } #[test] fn everything_executes() { let res = List::new(OkSymbol(true), OkSymbol(true)).execute(); assert_eq!(res.unwrap(), ()); } } */