use super::prelude::*;
pub fn collect<'p, 'r, 't, F>(
parser: &'p mut Parser<'r, 't>,
rule: Rule,
close_conditions: &[ParseCondition],
invalid_conditions: &[ParseCondition],
error_kind: Option<ParseErrorKind>,
mut process: F,
) -> ParseResult<'r, 't, &'r ExtractedToken<'t>>
where
F: FnMut(&mut Parser<'r, 't>) -> ParseResult<'r, 't, ()>,
{
debug!("Trying to collect tokens for rule {}", rule.name());
let mut errors = Vec::new();
let mut paragraph_safe = true;
loop {
if parser.evaluate_any(close_conditions) {
trace!(
"Found ending condition, returning collected elements (token {})",
parser.current().token.name(),
);
let last = parser.current();
if parser.current().token != Token::InputEnd {
parser.step()?;
}
return ok!(paragraph_safe; last, errors);
}
if parser.evaluate_any(invalid_conditions) {
trace!(
"Found invalid token, aborting container attempt (token {})",
parser.current().token.name(),
);
return Err(parser.make_err(error_kind.unwrap_or(ParseErrorKind::RuleFailed)));
}
if parser.current().token == Token::InputEnd {
trace!("Found end of input, aborting");
return Err(parser.make_err(ParseErrorKind::EndOfInput));
}
let old_remaining = parser.remaining();
process(parser)?.chain(&mut errors, &mut paragraph_safe);
if parser.same_pointer(old_remaining) {
parser.step()?;
}
}
}