use super::prelude::*;
use super::rule::{get_rules_for_token, impls::RULE_FALLBACK};
use super::Parser;
use crate::span_wrap::SpanWrap;
use std::mem;
pub fn consume<'p, 'r, 't>(
log: &slog::Logger,
parser: &'p mut Parser<'r, 't>,
) -> ParseResult<'r, 't, Elements<'t>> {
let log = &log.new(slog_o!(
"token" => parser.current().token,
"slice" => str!(parser.current().slice),
"span" => SpanWrap::from(&parser.current().span),
"remaining-len" => parser.remaining().len(),
));
parser.depth_increment()?;
debug!(log, "Looking for valid rules");
let mut all_exceptions = Vec::new();
let current = parser.current();
for &rule in get_rules_for_token(current) {
info!(log, "Trying rule consumption for tokens"; "rule" => rule);
let old_remaining = parser.remaining();
match rule.try_consume(log, parser) {
Ok(output) => {
debug!(log, "Rule matched, returning generated result"; "rule" => rule);
if parser.same_pointer(old_remaining) {
parser.step()?;
}
mem::drop(all_exceptions);
parser.depth_decrement();
return Ok(output);
}
Err(warning) => {
all_exceptions.push(ParseException::Warning(warning));
}
}
}
debug!(log, "All rules exhausted, using generic text fallback");
let element = text!(current.slice);
parser.step()?;
trace!(log, "Removing non-warnings from exceptions list");
all_exceptions.retain(|exception| matches!(exception, ParseException::Warning(_)));
if let Some(ParseException::Warning(warning)) = all_exceptions.last() {
if warning.kind() == ParseWarningKind::RecursionDepthExceeded {
trace!(log, "Found recursion depth error, failing");
return Err(warning.clone());
}
}
all_exceptions.push(ParseException::Warning(ParseWarning::new(
ParseWarningKind::NoRulesMatch,
RULE_FALLBACK,
current,
)));
parser.depth_decrement();
ok!(element, all_exceptions)
}