use super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
pub struct ManyUntil<'a, S, T> {
parser: &'a (Parser<S>+'a),
stop: &'a (Parser<T>+'a)
}
pub fn many_until<'a, S, T>(p: &'a (Parser<S> + 'a), s: &'a (Parser<T> + 'a)) -> ManyUntil<'a, S, T> {
return ManyUntil{parser: p, stop: s};
}
impl<'a, S, T> Parser<Vec<S>> for ManyUntil<'a, S, T> {
#[allow(unused_variables)]
fn _parse(&self, cs: &mut CharSeq) -> ParserResult<Vec<S>> {
let mut r = Vec::new();
let mut succ = true;
while succ {
match self.parser.parse(cs) {
Succ(c) => r.push(c),
Fail(m, l) => {
match self.stop.lookahead(cs) {
true => succ = false,
false => return Fail(m, l)
}
},
Error(m, l) => return Error(m, l)
}
}
return Succ(r);
}
}
#[cfg(test)]
#[allow(unused_variables)]
#[allow(unused_imports)]
mod tests {
use super::many_until;
use super::super::{CharSeq, ParserResult, EOF, Parser, Succ, Fail, Error};
#[test]
fn test_many_until1() {
let mut cs = CharSeq::new("aaa", "<mem>");
assert!(cs.pos == 0);
let s = "a";
let eof = EOF;
let m = many_until(&s, &eof);
match cs.accept(&m) {
Succ(v) => assert_eq!(v, vec!["a", "a", "a"]),
_ => assert!(false, "bug")
}
assert!(cs.pos == 3);
}
#[test]
fn test_many_until2() {
let mut cs = CharSeq::new("aaabbbccc", "<mem>");
assert!(cs.pos == 0);
let s = "a";
let eof = EOF;
let m = many_until(&s, &eof);
match cs.accept(&m) {
Fail(m, l) => assert_eq!(cs.pos, 3),
_ => assert!(false, "bug")
}
assert!(cs.pos == 3);
assert!(cs.view() == "bbbccc");
}
#[test]
fn test_many_until3() {
let mut cs = CharSeq::new("aaabbbccc", "<mem>");
assert!(cs.pos == 0);
let s = "x";
let eof = EOF;
let m = many_until(&s, &eof);
match cs.accept(&m) {
Fail(m, l) => {
assert_eq!(l.col,1);
assert_eq!(l.row,1);
},
Succ(a) => assert!(false, "bug"),
Error(m, l) => assert!(false, "bug: {} {}", m, l)
}
assert!(cs.pos == 0);
assert!(cs.view() == "aaabbbccc");
}
}