···11use super::*;
2233/// Consume tokens into a new parser until the concrete
44-/// parser returns `None`.
44+/// parser returns something. Stops when it hits `Some(_)`.
55///
66-/// Said concrete pattern here
77-/// is the generic parameter `Op`.
66+/// Said concrete pattern here is provided by
77+/// the generic parameter `Op`.
88pub struct CollectTill<Op: parsers::Operator>(Op);
99impl<Op> ConcreteSubparser<Op> for CollectTill<Op>
1010where
+37
src/parser/subparser/collect_while.rs
···11+use super::*;
22+33+/// Consume tokens into a new parser while the concrete
44+/// parser returns something. Stop consuming if it returns
55+/// `None`.
66+///
77+/// Said concrete pattern here is provided by
88+/// the generic parameter `Op`.
99+pub struct CollectWhile<Op: parsers::Operator>(Op);
1010+impl<Op> ConcreteSubparser<Op> for CollectWhile<Op>
1111+where
1212+ Op: parsers::Operator
1313+{
1414+ fn subparse
1515+ (value: <Op>::Input, parser: &mut Parser) -> Parser
1616+ where
1717+ Op: Container
1818+ {
1919+ let op = Op::new(value);
2020+2121+ let mut tokens = Tokens::new_empty();
2222+2323+ loop {
2424+ if let Some(_s) = op.peek_for(parser) {
2525+ if let Some(tok) = parser.next() {
2626+ tokens.add_token(tok)
2727+ } else {
2828+ panic!("Unexpected code path traced");
2929+ }
3030+ } else {
3131+ break;
3232+ }
3333+ }
3434+3535+ Parser::new(tokens)
3636+ }
3737+}
+23
tests/test_subparser.rs
···4545 }
4646 assert_eq!(Some(k), subparser.next())
4747 }
4848+}
4949+5050+#[test]
5151+fn test_collect_while_exact_match() {
5252+ let mut parser = setup_space_seps_parser(
5353+ "a a a a e f g h"
5454+ );
5555+ let mut known_subparser = setup_space_seps_parser(
5656+ "a a a a"
5757+ );
5858+5959+ let mut subparser = CollectWhile::<ExactMatch>::subparse(
6060+ "a".to_string(),
6161+ &mut parser
6262+ );
6363+6464+ println!("{:#?} {:#?}", known_subparser, subparser);
6565+6666+ let mut i: usize = 0;
6767+ while i < 4 {
6868+ assert_eq!(known_subparser.next(), subparser.next());
6969+ i += 1;
7070+ }
4871}