1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
use super::{CharSeq, ParserResult, Parser, Succ, Error, Fail}; pub struct Opt<'a, T:'a> { parser: &'a (Parser<T>+'a), default: T } pub fn opt<'a, T:Clone>(p:&'a (Parser<T>+'a), d: T) -> Opt<'a, T> { return Opt{parser: p, default: d}; } impl<'a, T: Clone> Parser<T> for Opt<'a, T> { #[allow(unused_variables)] fn parse(&self, cs: &mut CharSeq) -> ParserResult<T> { match self.parser.parse(cs) { Succ(c) => return Succ(c), Fail(m, l) => return Succ(self.default.clone()), Error(m, l) => return Error(m, l) } } fn _parse(&self, cs: &mut CharSeq) -> ParserResult<T> { Fail("".to_string(), cs.get_location()) } } #[cfg(test)] #[allow(unused_variables)] #[allow(unused_imports)] mod tests { use super::opt; use super::super::{CharSeq, ParserResult, Parser, Succ, Fail, Error}; #[test] fn test_opt1() { let mut cs = CharSeq::new("abcdefghi", "<mem>"); let s = "abc"; let o = opt(&s, "opt".to_string()); match cs.accept(&o) { Succ(c) => assert!(c.as_slice() == "abc"), Fail(a, b) => assert!(false, "failed"), Error(a, b) => assert!(false, "error") } } #[test] fn test_opt2() { let mut cs = CharSeq::new("abcdefghi", "<mem>"); let s = "xyz"; let o = opt(&s, "opt".to_string()); match cs.accept(&o) { Succ(c) => assert!(c.as_slice() == "opt"), Fail(a, b) => assert!(false, "failed"), Error(a, b) => assert!(false, "error") } } }