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
138 lines
3.5 KiB
use std::error::Error;
|
|
use std::fmt;
|
|
|
|
use resources::Resource;
|
|
use symbols::Symbol;
|
|
|
|
pub struct List<'a> {
|
|
symbols: Vec<Box<Symbol + 'a>>
|
|
}
|
|
|
|
impl<'a> List<'a> {
|
|
pub fn new(symbols: Vec<Box<Symbol + 'a>>) -> Self {
|
|
List { symbols: symbols }
|
|
}
|
|
}
|
|
|
|
impl<'a> Symbol for List<'a> {
|
|
fn target_reached(&self) -> Result<bool, Box<Error>> {
|
|
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<Error>> {
|
|
for symbol in &self.symbols {
|
|
try!(symbol.execute());
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
fn get_prerequisites(&self) -> Vec<Resource> {
|
|
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<Vec<Resource>> {
|
|
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<bool, Box<Error>> { Err(self.0.clone().into()) }
|
|
fn execute(&self) -> Result<(), Box<Error>> { 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<bool, Box<Error>> { Ok(self.0) }
|
|
fn execute(&self) -> Result<(), Box<Error>> { 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(), ());
|
|
}
|
|
}
|
|
*/
|