topdown-rs 0.0.1

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

pub struct Until<'a, T> {
    parser: &'a (Parser<T>+'a)
}

pub fn until<'a, T>(t:&'a (Parser<T>+'a)) -> Until<'a, T> {
    return Until{parser: t};
}

impl<'a, T> Parser<String> for Until<'a, T> {
    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<String> {
        let start = cs.pos;
        while !cs.eof() {
            if self.parser.lookahead(cs) {
                return Succ(cs.text.as_slice().slice(start, cs.pos).to_string());
            }
            cs.pos = cs.pos + 1;
        }
        return Succ(cs.text.as_slice().slice_from(start).to_string());
    }
}


#[cfg(test)]
#[allow(unused_variables)]
#[allow(unused_imports)]
mod tests {
    use super::until;
    use super::super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
    #[test]
    fn test_until1() {
        let mut cs = CharSeq::new("abcabcdef", "<mem>");
        let x = "def";
        let ut = until(&x);
        match cs.accept(&ut) {
            Succ(c) => assert!(c.as_slice() == "abcabc"),
            _ => assert!(false, "bug")
        }
        assert!(cs.pos == 6);
    }

    #[test]
    fn test_until2() {
        let mut cs = CharSeq::new("abcdefghi", "<mem>");
        let x = "def";
        let ut = until(&x);
        match cs.accept(&ut) {
            Succ(c) => assert!(c.as_slice() == "abc"),
            _ => assert!(false, "bug")
        }
        assert!(cs.pos == 3);
    }

    #[test]
    fn test_until3() {
        let mut cs = CharSeq::new("abcdefghi", "<mem>");
        let x = "klm";
        let ut = until(&x);
        match cs.accept(&ut) {
            Succ(c) => {
                assert_eq!(c.as_slice(), "abcdefghi");
            },
            _ => assert!(false, "bug")
        }
        assert!(cs.pos == 9);
    }
}