topdown/
opt.rs

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