use super::Parser;
use super::prelude::*;
use super::rule::{get_rules_for_token, impls::RULE_FALLBACK};
use std::mem;
pub fn consume<'r, 't>(parser: &mut Parser<'r, 't>) -> ParseResult<'r, 't, Elements<'t>> {
debug!(
"Running consume attempt (token {}, slice {:?})",
parser.current().token.name(),
parser.current().slice,
);
parser.depth_increment()?;
trace!("Looking for valid rules");
let mut all_errors = Vec::new();
let current = parser.current();
for &rule in get_rules_for_token(current) {
trace!("Trying rule consumption for tokens (rule {})", rule.name());
let old_remaining = parser.remaining();
let footnote_count = parser.footnote_count();
match rule.try_consume(parser) {
Ok(output) => {
debug!("Rule {} matched, returning generated result", rule.name());
if parser.same_pointer(old_remaining) {
parser.step()?;
}
mem::drop(all_errors);
parser.depth_decrement();
return Ok(output);
}
Err(error) => {
warn!("Rule failed, returning error: '{}'", error.kind().name());
parser.truncate_footnotes(footnote_count);
all_errors.push(error);
}
}
}
warn!("All rules exhausted, using generic text fallback");
let element = text!(current.slice);
parser.step()?;
if let Some(error) = all_errors.last()
&& error.kind() == ParseErrorKind::RecursionDepthExceeded
{
error!("Found recursion depth error, failing");
return Err(error.clone());
}
all_errors.push(ParseError::new(
ParseErrorKind::NoRulesMatch,
RULE_FALLBACK,
current,
));
parser.depth_decrement();
ok!(element, all_errors)
}