topdown-rs 0.3.2

A top-down parsing library
use super::{CharSeq, ParserResult, Parser, ParserHook};

pub struct FunctionWrapper<F, T> {
    func: F
}

impl<F, T> Parser<T> for FunctionWrapper<F, T> where F: Fn(&mut CharSeq) -> ParserResult<T> {
    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<T> {
        self.func.call((cs,))
    }
}

impl<F, T> ParserHook for FunctionWrapper<F, T> where F: Fn(&mut CharSeq) -> ParserResult<T> {
    fn hook(&self, cs: &mut CharSeq)  {
        self.func.call((cs,));
    }
}

pub fn wrap<F, T>(f: F) -> FunctionWrapper<F, T> where F: Fn(&mut CharSeq) -> ParserResult<T> {
    FunctionWrapper{func: f}
}

#[cfg(test)]
#[allow(unused_variables)]
#[allow(unused_imports)]
mod tests {
    use super::wrap;
    use super::super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};

    fn some_parser(cs: &mut CharSeq) -> ParserResult<Vec<String>> {
        let x = "abc";
        let y = "def";
        let z = "ghi";
        cs.accept(&x).and_then(|a|
            cs.accept(&y).and_then(|b|
            cs.accept(&z).map(|c| {
                vec!(a.to_string(), b.to_string(), c.to_string())
            }
        )))
    }

    #[test]
    fn test_wrap1() {
        let mut cs = CharSeq::new("abcdefghi", "");
        let w = wrap(some_parser);
        match cs.accept(&w) {
            Succ(x) => assert_eq!(x, vec!("abc".to_string(), "def".to_string(), "ghi".to_string())),
            Fail(m, l) => assert!(false, "failed"),
            Error(m, l) => assert!(false, "error")
        }
    }

    #[test]
    fn test_wrap2() {
        let w = wrap(some_parser);
        let mut cs = CharSeq::new("abcdefghixxxabcdefghi", "");
        cs.add_hook(&w);
        match cs.accept(&"xxx") {
            Succ(x) => assert_eq!(x.as_slice(), "xxx"),
            Fail(m, l) => assert!(false, "failed"),
            Error(m, l) => assert!(false, "error")
        }
    }
}