···16 C: concrete_parser::ContainerCp;
17}
1819+/// Functionality to build blanket [Parsers](Parser) using
20+/// a parent [Parser] by consuming a list of tokens from it.
21+pub trait VariadicConcreteSubparser<C> {
22+ /// Build the subparser based on the concrete parser.
23+ fn subparse
24+ (values: Vec<C::Input>, parser: &mut Parser) -> Parser
25+ where
26+ C: concrete_parser::ContainerCp;
27+}
28+29mod collect_till;
30mod collect_while;
31+mod collect_if_sequence;
32pub use {
33 collect_till::CollectTill,
34 collect_while::CollectWhile,
35+ collect_if_sequence::{CollectIfSeq, CollectIfExactSeq},
36+};
···1+use crate::prelude::*;
2+3+/// Consume a sequence of tokens into a new parser while the
4+/// concrete parsers return something. Stop consuming once
5+/// all values are exhausted, or if one of then returned
6+/// `None`.
7+pub struct CollectIfSeq<Cp: ConcreteParser>(Cp);
8+impl<Cp> VariadicConcreteSubparser<Cp> for CollectIfSeq<Cp>
9+where
10+ Cp: ConcreteParser
11+{
12+ fn subparse
13+ (values: Vec<Cp::Input>, parser: &mut Parser) -> Parser
14+ where
15+ Cp: concrete_parser::ContainerCp
16+ {
17+ let mut tokens = Tokens::new_empty();
18+19+ for v in values {
20+ let cp = Cp::new(v);
21+22+ if let Some(token) = cp.try_next_token(parser) {
23+ tokens.add_token(token);
24+ }
25+ }
26+27+ Parser::new(tokens)
28+ }
29+}
30+31+/// Consume a sequence of tokens into a new parser **if**
32+/// the coming sequence of tokens match a sequence.
33+pub struct CollectIfExactSeq<Cp: ConcreteParser>(Cp);
34+impl<Cp> VariadicConcreteSubparser<Cp> for CollectIfExactSeq<Cp>
35+where
36+ Cp: ConcreteParser
37+{
38+ fn subparse
39+ (values: Vec<Cp::Input>, parser: &mut Parser) -> Parser
40+ where
41+ Cp: concrete_parser::ContainerCp
42+ {
43+ let mut toks_buffer: Tokens = Tokens::new_empty();
44+45+ let mut exact: bool = true;
46+47+ for v in values {
48+ let cp = Cp::new(v);
49+50+ if let Some(token) = cp.try_next_token(parser) {
51+ toks_buffer.add_token(token)
52+ } else {
53+ if let Some(token) = parser.next() {
54+ toks_buffer.add_token(token);
55+ }
56+ exact = false;
57+ }
58+ }
59+60+ if exact {
61+ Parser::new(toks_buffer)
62+ } else {
63+ parser.extend(toks_buffer);
64+ Parser::new_empty()
65+ }
66+ }
67+}
+1-4
src/parser/subparser/collect_while.rs
···3/// Consume tokens into a new parser while the concrete
4/// parser returns something. Stop consuming if it returns
5/// `None`.
6-///
7-/// Said concrete pattern here is provided by
8-/// the generic parameter `Op`.
9pub struct CollectWhile<Op: ConcreteParser>(Op);
10impl<Op> ConcreteSubparser<Op> for CollectWhile<Op>
11where
···3031 Parser::new(tokens)
32 }
33-}
···3/// Consume tokens into a new parser while the concrete
4/// parser returns something. Stop consuming if it returns
5/// `None`.
0006pub struct CollectWhile<Op: ConcreteParser>(Op);
7impl<Op> ConcreteSubparser<Op> for CollectWhile<Op>
8where
···2728 Parser::new(tokens)
29 }
30+}