Crate repl [−] [src]
R(ead), E(val), P(rint), L(oop)
use repl::{Repl, ReplEnv}; use self::CmdType::*; use self::Exp::*; use self::ReplErr::{Read, Eval}; use std::default::Default; use std::fmt; pub struct MyRepl; #[derive(Default)] pub struct MyReplEnv { prompt: String, } impl ReplEnv for MyReplEnv { fn preamble(&self) -> bool { false } fn colorize(&self) -> bool { false } fn prompt(&self) -> &str { &self.prompt } } pub enum CmdType { Open, Close, } pub enum Exp { Cmd(CmdType), Strn(String), Exit, Nil, } pub enum ReplErr { Read(&'static str), Eval(&'static str), // Print(String), } impl fmt::Display for ReplErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let x = match *self { Read(ref x) => x, Eval(ref x) => x, // Print(ref x) => x, }; write!(f, "{}", x) } } pub type MyReplResult = Result<Exp, ReplErr>; impl Repl<Exp, ReplErr, MyReplEnv> for MyRepl { fn preamble(&self, _: &MyReplEnv) -> &MyRepl { self } fn read(&self, input: String, _: &MyReplEnv) -> MyReplResult { match &input[..] { "open" | "close" | "exit" => Ok(Strn(input)), _ => Err(Read("invalid input")), } } fn eval(&self, cmd: Exp, _: &MyReplEnv) -> MyReplResult { match cmd { Strn(ref x) if *x == "open" => Ok(Cmd(Open)), Strn(ref x) if *x == "close" => Ok(Cmd(Close)), Strn(ref x) if *x == "exit" => Ok(Exit), _ => Err(Eval("invalid ast")), } } fn print(&self, cmd: Exp, _: &MyReplEnv) -> MyReplResult { match cmd { Cmd(Open) => { println!("opening..."); Ok(Nil) } Cmd(Close) => { println!("closing..."); Ok(Nil) } Exit => { println!("exiting..."); Ok(Exit) } _ => Ok(Nil), } } fn break_loop(&self, cmd: &Exp, _: &MyReplEnv) -> bool { match *cmd { Exit => true, _ => false, } } } fn main() { let repl = MyRepl; let env: MyReplEnv = Default::default(); test_read(&repl, &env); test_eval(&repl, &env); test_print(&repl, &env); test_read_eval_print(&repl, &env); test_break_loop(&repl, &env); } fn test_read(repl: &MyRepl, env: &MyReplEnv) { assert!(repl.read("open".to_owned(), env).is_ok()); assert!(repl.read("close".to_owned(), env).is_ok()); assert!(repl.read("exit".to_owned(), env).is_ok()); assert!(repl.read("blah".to_owned(), env).is_err()); } fn test_eval(repl: &MyRepl, env: &MyReplEnv) { assert!(repl.eval(Strn("open".to_owned()), &env).is_ok()); assert!(repl.eval(Strn("close".to_owned()), &env).is_ok()); assert!(repl.eval(Strn("exit".to_owned()), &env).is_ok()); assert!(repl.eval(Nil, &env).is_err()); } fn test_print(repl: &MyRepl, env: &MyReplEnv) { assert!(repl.print(Cmd(Open), &env).is_ok()); assert!(repl.print(Cmd(Close), &env).is_ok()); assert!(repl.print(Exit, &env).is_ok()); assert!(repl.print(Nil, &env).is_ok()); } fn test_read_eval_print(repl: &MyRepl, env: &MyReplEnv) { assert!(repl.read("open".to_owned(), &env) .and_then(|r| repl.eval(r, &env)) .and_then(|r| repl.print(r, &env)) .is_ok()); assert!(repl.read("close".to_owned(), &env) .and_then(|r| repl.eval(r, &env)) .and_then(|r| repl.print(r, &env)) .is_ok()); assert!(repl.read("blah".to_owned(), &env) .and_then(|r| repl.eval(r, &env)) .and_then(|r| repl.print(r, &env)) .is_err()); } fn test_break_loop(repl: &MyRepl, env: &MyReplEnv) { assert!(repl.break_loop(&Exit, &env)); assert!(!repl.break_loop(&Cmd(Open), &env)); }
Reexports
pub use self::ReplErr::Read; |
pub use self::ReplErr::Eval; |
pub use self::ReplErr::Print; |
Modules
version |
version string generation by vergen. |
Enums
ReplErr |
|
Traits
Repl |
|
ReplEnv |
The repl environment trait |