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