use super::Rule;
use pest::iterators::Pairs;
pub(super) struct Children<'i> {
rule: Rule,
inner: Pairs<'i, Rule>,
taken: usize,
}
impl<'i> Children<'i> {
pub(super) fn of(node: pest::iterators::Pair<'i, Rule>) -> Self {
Children {
rule: node.as_rule(),
inner: node.into_inner(),
taken: 0,
}
}
pub(super) fn required(&mut self) -> Result<pest::iterators::Pair<'i, Rule>, String> {
match self.next() {
Some(child) => Ok(child),
None => Err(format!(
"internal error: grammar rule {:?} has no child {}",
self.rule,
self.taken + 1
)),
}
}
pub(super) fn unexpected(&self, child: &pest::iterators::Pair<'_, Rule>) -> String {
format!(
"internal error: grammar rule {:?} has unexpected child {:?}",
self.rule,
child.as_rule()
)
}
}
impl<'i> Iterator for Children<'i> {
type Item = pest::iterators::Pair<'i, Rule>;
fn next(&mut self) -> Option<Self::Item> {
let child = self.inner.next();
if child.is_some() {
self.taken += 1;
}
child
}
}
pub(super) fn unexpected_text(rule: Rule, text: &str) -> String {
format!("internal error: grammar rule {rule:?} matched unexpected text {text:?}")
}