2 changed files with 104 additions and 0 deletions
			
			
		@ -0,0 +1,103 @@ | 
			
		|||||
 | 
				use std::error::Error;
 | 
			
		||||
 | 
				use std::fmt;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				use symbols::Symbol;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				pub struct Hook<A, B> where A: Symbol, B: Symbol {
 | 
			
		||||
 | 
				  a: A,
 | 
			
		||||
 | 
				  b: B
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<A, B> Hook<A, B> where A: Symbol, B: Symbol {
 | 
			
		||||
 | 
				  pub fn new(a: A, b: B) -> Self {
 | 
			
		||||
 | 
				    Hook { a: a, b: b }
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<A, B> Symbol for Hook<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>> {
 | 
			
		||||
 | 
				    try!(self.a.execute());
 | 
			
		||||
 | 
				    self.b.execute()
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				impl<A, B> fmt::Display for Hook<A, B> where A: Symbol, B: Symbol {
 | 
			
		||||
 | 
				  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>{
 | 
			
		||||
 | 
				    write!(f, "Hook {} and then {}", self.a, self.b)
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				#[cfg(test)]
 | 
			
		||||
 | 
				mod test {
 | 
			
		||||
 | 
				  use std::error::Error;
 | 
			
		||||
 | 
				  use std::fmt;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  use symbols::Symbol;
 | 
			
		||||
 | 
				  use symbols::hook::Hook;
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  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 = Hook::new(ErrSymbol("first".into()), ErrSymbol("second".into())).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "first");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn first_target_not_reached() {
 | 
			
		||||
 | 
				    let res = Hook::new(OkSymbol(false), ErrSymbol("second".into())).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), false);
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn second_target_reached_fails() {
 | 
			
		||||
 | 
				    let res = Hook::new(OkSymbol(true), ErrSymbol("second".into())).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "second");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn second_target_not_reached() {
 | 
			
		||||
 | 
				    let res = Hook::new(OkSymbol(true), OkSymbol(false)).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), false);
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn everything_reached() {
 | 
			
		||||
 | 
				    let res = Hook::new(OkSymbol(true), OkSymbol(true)).target_reached();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), true);
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn first_execute_fails() {
 | 
			
		||||
 | 
				    let res = Hook::new(ErrSymbol("first".into()), ErrSymbol("second".into())).execute();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "first");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn second_execute_fails() {
 | 
			
		||||
 | 
				    let res = Hook::new(OkSymbol(true), ErrSymbol("second".into())).execute();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap_err().description(), "second");
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				
 | 
			
		||||
 | 
				  #[test]
 | 
			
		||||
 | 
				  fn everything_executes() {
 | 
			
		||||
 | 
				    let res = Hook::new(OkSymbol(true), OkSymbol(true)).execute();
 | 
			
		||||
 | 
				    assert_eq!(res.unwrap(), ());
 | 
			
		||||
 | 
				  }
 | 
			
		||||
 | 
				}
 | 
			
		||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue