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