···5959 self.0.push_back(token)
6060 }
61616262+ /// Get [Tokens] from a vector of [Token] items.
6363+ pub fn from_vec(toks: Vec<Token>) -> Tokens {
6464+ Tokens(
6565+ VecDeque::from(toks)
6666+ )
6767+ }
6868+6269 /// Get a new empty list of tokens.
6370 pub fn new_empty() -> Tokens {
6471 Tokens(VecDeque::new())
+25-1
src/parser.rs
···1414 self.tokens.peek().cloned()
1515 }
16161717+ /// Extend the parser with [Tokens].
1818+ ///
1919+ /// Current implementation *could be*
2020+ /// costly as it relies on cloning.
2121+ pub fn extend(&mut self, tokens: Tokens) {
2222+ let mut toks_buf = Tokens::new_empty();
2323+2424+ for token in self.clone() {
2525+ toks_buf.add_token(token);
2626+ }
2727+2828+ for token in tokens.clone() {
2929+ toks_buf.add_token(token);
3030+ }
3131+3232+ self.tokens = tokens.peekable();
3333+ }
3434+3535+ /// Get a new empty [Parser].
3636+ pub fn new_empty() -> Parser {
3737+ let tokens = Tokens::new_empty();
3838+ Self::new(tokens)
3939+ }
4040+1741 /// Create a new [Parser] from tokens.
1842 pub fn new(tokens: Tokens) -> Parser {
1943 Parser { tokens: tokens.peekable() }
···3963}
40644165pub mod concrete_parser;
4242-pub mod subparser;6666+pub mod subparser;
+13-1
src/parser/subparser.rs
···1616 C: concrete_parser::ContainerCp;
1717}
18181919+/// Functionality to build blanket [Parsers](Parser) using
2020+/// a parent [Parser] by consuming a list of tokens from it.
2121+pub trait VariadicConcreteSubparser<C> {
2222+ /// Build the subparser based on the concrete parser.
2323+ fn subparse
2424+ (values: Vec<C::Input>, parser: &mut Parser) -> Parser
2525+ where
2626+ C: concrete_parser::ContainerCp;
2727+}
2828+1929mod collect_till;
2030mod collect_while;
3131+mod collect_if_sequence;
2132pub use {
2233 collect_till::CollectTill,
2334 collect_while::CollectWhile,
2424-};3535+ collect_if_sequence::{CollectIfSeq, CollectIfExactSeq},
3636+};
+67
src/parser/subparser/collect_if_sequence.rs
···11+use crate::prelude::*;
22+33+/// Consume a sequence of tokens into a new parser while the
44+/// concrete parsers return something. Stop consuming once
55+/// all values are exhausted, or if one of then returned
66+/// `None`.
77+pub struct CollectIfSeq<Cp: ConcreteParser>(Cp);
88+impl<Cp> VariadicConcreteSubparser<Cp> for CollectIfSeq<Cp>
99+where
1010+ Cp: ConcreteParser
1111+{
1212+ fn subparse
1313+ (values: Vec<Cp::Input>, parser: &mut Parser) -> Parser
1414+ where
1515+ Cp: concrete_parser::ContainerCp
1616+ {
1717+ let mut tokens = Tokens::new_empty();
1818+1919+ for v in values {
2020+ let cp = Cp::new(v);
2121+2222+ if let Some(token) = cp.try_next_token(parser) {
2323+ tokens.add_token(token);
2424+ }
2525+ }
2626+2727+ Parser::new(tokens)
2828+ }
2929+}
3030+3131+/// Consume a sequence of tokens into a new parser **if**
3232+/// the coming sequence of tokens match a sequence.
3333+pub struct CollectIfExactSeq<Cp: ConcreteParser>(Cp);
3434+impl<Cp> VariadicConcreteSubparser<Cp> for CollectIfExactSeq<Cp>
3535+where
3636+ Cp: ConcreteParser
3737+{
3838+ fn subparse
3939+ (values: Vec<Cp::Input>, parser: &mut Parser) -> Parser
4040+ where
4141+ Cp: concrete_parser::ContainerCp
4242+ {
4343+ let mut toks_buffer: Tokens = Tokens::new_empty();
4444+4545+ let mut exact: bool = true;
4646+4747+ for v in values {
4848+ let cp = Cp::new(v);
4949+5050+ if let Some(token) = cp.try_next_token(parser) {
5151+ toks_buffer.add_token(token)
5252+ } else {
5353+ if let Some(token) = parser.next() {
5454+ toks_buffer.add_token(token);
5555+ }
5656+ exact = false;
5757+ }
5858+ }
5959+6060+ if exact {
6161+ Parser::new(toks_buffer)
6262+ } else {
6363+ parser.extend(toks_buffer);
6464+ Parser::new_empty()
6565+ }
6666+ }
6767+}
+1-4
src/parser/subparser/collect_while.rs
···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`.
96pub struct CollectWhile<Op: ConcreteParser>(Op);
107impl<Op> ConcreteSubparser<Op> for CollectWhile<Op>
118where
···30273128 Parser::new(tokens)
3229 }
3333-}3030+}
+131
tests/test_subparser.rs
···33mod common;
44use common::*;
5566+/// Assert that two parsers successively yield a certain number
77+/// `n` of the same token.
88+fn assert_parsers_same_till(
99+ mut a: Parser,
1010+ mut b: Parser,
1111+ n: usize
1212+) {
1313+ let mut i: usize = 0;
1414+ while i < n {
1515+ assert_eq!(a.next(), b.next());
1616+ i += 1;
1717+ }
1818+}
1919+2020+fn not_assert_parsers_same_till(
2121+ mut a: Parser,
2222+ mut b: Parser,
2323+ n: usize
2424+) {
2525+ let mut i: usize = 0;
2626+ let mut not: bool = false;
2727+ while i < n {
2828+ if a.next() != b.next() {
2929+ not = true;
3030+ break;
3131+ }
3232+ i += i;
3333+ }
3434+ assert!(not)
3535+}
3636+637#[test]
738fn test_collect_till_exact_match_subparser() {
839 let mut parser = setup_space_seps_parser(
···6495 assert_eq!(known_subparser.next(), subparser.next());
6596 i += 1;
6697 }
9898+}
9999+100100+#[test]
101101+fn test_collect_if_sequence() {
102102+ let mut parser = setup_space_seps_parser(
103103+ "a b c d e f g h i j"
104104+ );
105105+ let known_subparser = setup_space_seps_parser(
106106+ "a b c d"
107107+ );
108108+109109+ let values: Vec<String> = vec!["a", "b", "c", "d", "e"]
110110+ .into_iter()
111111+ .map(String::from)
112112+ .collect();
113113+114114+ let subparser = CollectIfSeq::<ExactMatch>::subparse(
115115+ values,
116116+ &mut parser
117117+ );
118118+119119+ assert_parsers_same_till(
120120+ known_subparser,
121121+ subparser,
122122+ 4
123123+ );
124124+}
125125+126126+#[test]
127127+fn test_collect_if_exact_sequence() {
128128+ let mut parser = setup_space_seps_parser(
129129+ "a b c d e f g h i j"
130130+ );
131131+ let known_subparser = setup_space_seps_parser(
132132+ "a b"
133133+ );
134134+135135+ let values: Vec<String> = vec!["a", "b", "c", "d"]
136136+ .into_iter()
137137+ .map(String::from)
138138+ .collect();
139139+140140+ let subparser = CollectIfExactSeq::<ExactMatch>::subparse(
141141+ values,
142142+ &mut parser
143143+ );
144144+145145+ assert_parsers_same_till(
146146+ known_subparser,
147147+ subparser,
148148+ 2
149149+ );
150150+}
151151+152152+#[test]
153153+fn test_fail_collect_if_exact_sequence() {
154154+ let mut parser = setup_space_seps_parser(
155155+ "a b c d e f g h i j"
156156+ );
157157+ let known_subparser = setup_space_seps_parser(
158158+ "a b c d"
159159+ );
160160+161161+ let values: Vec<String> = vec!["a", "b", "c", "d", "f"]
162162+ .into_iter()
163163+ .map(String::from)
164164+ .collect();
165165+166166+ let subparser = CollectIfExactSeq::<ExactMatch>::subparse(
167167+ values,
168168+ &mut parser
169169+ );
170170+171171+ not_assert_parsers_same_till(
172172+ known_subparser,
173173+ subparser,
174174+ 4
175175+ );
176176+}
177177+178178+#[test]
179179+fn test_fail_collect_if_exact_keeps_parent_parser_intact() {
180180+ let mut parser = setup_space_seps_parser(
181181+ "a b c d"
182182+ );
183183+ let initial_parser = parser.clone();
184184+185185+ let values: Vec<String> = vec!["a", "b", "c", "e"]
186186+ .into_iter()
187187+ .map(String::from)
188188+ .collect();
189189+190190+ let _subparser = CollectIfExactSeq::<ExactMatch>::subparse(
191191+ values,
192192+ &mut parser
193193+ );
194194+195195+ println!("{:#?}", parser);
196196+197197+ assert_parsers_same_till(parser, initial_parser, 4);
67198}