use crate::prelude::*; /// Consume a sequence of tokens into a new parser while the /// concrete parsers return something. Stop consuming once /// all values are exhausted, or if one of then returned /// `None`. pub struct CollectIfSeq(Cp); impl VariadicConcreteSubparser for CollectIfSeq where Cp: ConcreteParser { fn subparse (values: Vec, parser: &mut Parser) -> Parser where Cp: concrete_parser::ContainerCp { let mut tokens = Tokens::new_empty(); for v in values { let cp = Cp::new(v); if let Some(token) = cp.try_next_token(parser) { tokens.add_token(token); } } Parser::new(tokens) } } /// Consume a sequence of tokens into a new parser **if** /// the coming sequence of tokens match a sequence. pub struct CollectIfExactSeq(Cp); impl VariadicConcreteSubparser for CollectIfExactSeq where Cp: ConcreteParser { fn subparse (values: Vec, parser: &mut Parser) -> Parser where Cp: concrete_parser::ContainerCp { let mut toks_buffer: Tokens = Tokens::new_empty(); let mut exact: bool = true; for v in values { let cp = Cp::new(v); if let Some(token) = cp.try_next_token(parser) { toks_buffer.add_token(token) } else { if let Some(token) = parser.next() { toks_buffer.add_token(token); } exact = false; } } if exact { Parser::new(toks_buffer) } else { parser.extend(toks_buffer); Parser::new_empty() } } }