5 changed files with 34 additions and 157 deletions
			
			
		- 
					22src/schema.rs
 - 
					14src/symbols/hook.rs
 - 
					144src/symbols/if_already_present.rs
 - 
					9src/symbols/mod.rs
 - 
					2src/symbols/user.rs
 
@ -1,144 +0,0 @@ | 
				
			|||
use std::error::Error;
 | 
				
			|||
use std::fmt;
 | 
				
			|||
 | 
				
			|||
use resources::Resource;
 | 
				
			|||
use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
 | 
				
			|||
 | 
				
			|||
pub struct IfAlreadyPresent<A, B> where A: Symbol, B: Symbol {
 | 
				
			|||
  a: A,
 | 
				
			|||
  b: B
 | 
				
			|||
}
 | 
				
			|||
 | 
				
			|||
impl<A, B> IfAlreadyPresent<A, B> where A: Symbol, B: Symbol {
 | 
				
			|||
  pub fn new(a: A, b: B) -> Self {
 | 
				
			|||
    IfAlreadyPresent { a: a, b: b }
 | 
				
			|||
  }
 | 
				
			|||
}
 | 
				
			|||
 | 
				
			|||
impl<A, B> Symbol for IfAlreadyPresent<A, B> where A: Symbol, B: Symbol {
 | 
				
			|||
  fn target_reached(&self) -> Result<bool, Box<Error>> {
 | 
				
			|||
    self.a.target_reached().and_then(|reached| if reached { self.b.target_reached() } else { Ok(reached) })
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  fn execute(&self) -> Result<(), Box<Error>> {
 | 
				
			|||
    // Execute a & b if a is not reached
 | 
				
			|||
    // Execute b if a was reached and b isn't
 | 
				
			|||
    if !try!(self.a.target_reached()) {
 | 
				
			|||
      try!(self.a.execute());
 | 
				
			|||
      self.b.execute()
 | 
				
			|||
    } else if !try!(self.b.target_reached()) {
 | 
				
			|||
      self.b.execute()
 | 
				
			|||
    } else {
 | 
				
			|||
      Ok(())
 | 
				
			|||
    }
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  fn get_prerequisites(&self) -> Vec<Resource> {
 | 
				
			|||
    let mut r = vec![];
 | 
				
			|||
    r.extend(self.a.get_prerequisites().into_iter());
 | 
				
			|||
    r.extend(self.b.get_prerequisites().into_iter());
 | 
				
			|||
    r
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  fn provides(&self) -> Option<Vec<Resource>> {
 | 
				
			|||
    let mut r = vec![];
 | 
				
			|||
    if let Some(provides) = self.a.provides() {
 | 
				
			|||
      r.extend(provides.into_iter());
 | 
				
			|||
    }
 | 
				
			|||
    if let Some(provides) = self.b.provides() {
 | 
				
			|||
      r.extend(provides.into_iter());
 | 
				
			|||
    }
 | 
				
			|||
    if r.len() > 0 { Some(r) } else { None }
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  fn as_action<'a>(&'a self, runner: &'a SymbolRunner) -> Box<Action + 'a> {
 | 
				
			|||
    Box::new(SymbolAction::new(runner, self))
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  fn into_action<'a>(self: Box<Self>, runner: &'a SymbolRunner) -> Box<Action + 'a> where Self: 'a {
 | 
				
			|||
    Box::new(OwnedSymbolAction::new(runner, *self))
 | 
				
			|||
  }
 | 
				
			|||
}
 | 
				
			|||
 | 
				
			|||
impl<A, B> fmt::Display for IfAlreadyPresent<A, B> where A: Symbol, B: Symbol {
 | 
				
			|||
  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{
 | 
				
			|||
    write!(f, "IfAlreadyPresent {} and then {}", self.a, self.b)
 | 
				
			|||
  }
 | 
				
			|||
}
 | 
				
			|||
 | 
				
			|||
#[cfg(test)]
 | 
				
			|||
mod test {
 | 
				
			|||
  use std::error::Error;
 | 
				
			|||
  use std::fmt;
 | 
				
			|||
 | 
				
			|||
  use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
 | 
				
			|||
  use symbols::if_already_present::IfAlreadyPresent;
 | 
				
			|||
 | 
				
			|||
  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 = IfAlreadyPresent::new(ErrSymbol("first".into()), ErrSymbol("second".into())).target_reached();
 | 
				
			|||
    assert_eq!(res.unwrap_err().description(), "first");
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn first_target_not_reached() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(OkSymbol(false), ErrSymbol("second".into())).target_reached();
 | 
				
			|||
    assert_eq!(res.unwrap(), false);
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn second_target_reached_fails() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(OkSymbol(true), ErrSymbol("second".into())).target_reached();
 | 
				
			|||
    assert_eq!(res.unwrap_err().description(), "second");
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn second_target_not_reached() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(OkSymbol(true), OkSymbol(false)).target_reached();
 | 
				
			|||
    assert_eq!(res.unwrap(), false);
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn everything_reached() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(OkSymbol(true), OkSymbol(true)).target_reached();
 | 
				
			|||
    assert_eq!(res.unwrap(), true);
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn first_execute_fails() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(ErrSymbol("first".into()), ErrSymbol("second".into())).execute();
 | 
				
			|||
    assert_eq!(res.unwrap_err().description(), "first");
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn second_execute_fails_but_isnt_run() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(OkSymbol(false), ErrSymbol("second".into())).execute();
 | 
				
			|||
    assert_eq!(res.unwrap(), ());
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn second_execute_fails() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(OkSymbol(true), ErrSymbol("second".into())).execute();
 | 
				
			|||
    assert_eq!(res.unwrap_err().description(), "second");
 | 
				
			|||
  }
 | 
				
			|||
 | 
				
			|||
  #[test]
 | 
				
			|||
  fn everything_executes() {
 | 
				
			|||
    let res = IfAlreadyPresent::new(OkSymbol(true), OkSymbol(true)).execute();
 | 
				
			|||
    assert_eq!(res.unwrap(), ());
 | 
				
			|||
  }
 | 
				
			|||
}
 | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue