1use super::{CharSeq, ParserResult, Parser, Succ, Fail, Error};
2
3
4pub struct ManyUntil<'a, S:'a, T:'a> {
5 parser: &'a (Parser<S>+'a),
6 stop: &'a (Parser<T>+'a)
7}
8
9pub fn many_until<'a, S, T>(p: &'a (Parser<S> + 'a), s: &'a (Parser<T> + 'a)) -> ManyUntil<'a, S, T> {
10 return ManyUntil{parser: p, stop: s};
11}
12
13impl<'a, S, T> Parser<Vec<S>> for ManyUntil<'a, S, T> {
14 #[allow(unused_variables)]
15 fn _parse(&self, cs: &mut CharSeq) -> ParserResult<Vec<S>> {
16 let mut r = Vec::new();
17 let mut succ = true;
18 while succ {
19 match self.parser.parse(cs) {
20 Succ(c) => r.push(c),
21 Fail(m, l) => {
22 match self.stop.lookahead(cs) {
23 true => succ = false,
24 false => return Fail(m, l)
25 }
26 },
27 Error(m, l) => return Error(m, l)
28 }
29 }
30 return Succ(r);
31 }
32}
33
34
35#[cfg(test)]
36#[allow(unused_variables)]
37#[allow(unused_imports)]
38mod tests {
39 use super::many_until;
40 use super::super::{CharSeq, ParserResult, EOF, Parser, Succ, Fail, Error};
41
42 #[test]
43 fn test_many_until1() {
44 let mut cs = CharSeq::new("aaa", "<mem>");
45 assert!(cs.pos == 0);
46 let s = "a";
47 let eof = EOF;
48 let m = many_until(&s, &eof);
49 match cs.accept(&m) {
50 Succ(v) => assert_eq!(v, vec!["a", "a", "a"]),
51 _ => assert!(false, "bug")
52 }
53 assert!(cs.pos == 3);
54 }
55
56 #[test]
57 fn test_many_until2() {
58 let mut cs = CharSeq::new("aaabbbccc", "<mem>");
59 assert!(cs.pos == 0);
60 let s = "a";
61 let eof = EOF;
62 let m = many_until(&s, &eof);
63 match cs.accept(&m) {
64 Fail(m, l) => assert_eq!(cs.pos, 3),
65 _ => assert!(false, "bug")
66 }
67 assert!(cs.pos == 3);
68 assert!(cs.view() == "bbbccc");
69 }
70
71 #[test]
72 fn test_many_until3() {
73 let mut cs = CharSeq::new("aaabbbccc", "<mem>");
74 assert!(cs.pos == 0);
75 let s = "x";
76 let eof = EOF;
77 let m = many_until(&s, &eof);
78 match cs.accept(&m) {
79 Fail(m, l) => {
80 assert_eq!(l.col,1);
81 assert_eq!(l.row,1);
82 },
83 Succ(a) => assert!(false, "bug"),
84 Error(m, l) => assert!(false, "bug: {} {}", m, l)
85 }
86 assert!(cs.pos == 0);
87 assert!(cs.view() == "aaabbbccc");
88 }
89}
90