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")
        }
    }
}