use super::{AsNode, Node, NodePropertiesIter};
use crate::{
helpers::{FallibleNode, FallibleParser},
parsing::{NoPanic, ParserWithMode},
};
#[derive(Debug, Clone, Copy)]
pub struct Aliases<'a, P: ParserWithMode<'a>> {
pub(crate) node: FallibleNode<'a, P>,
}
impl<'a, P: ParserWithMode<'a>> Aliases<'a, P> {
pub fn resolve_name(self, alias: &str) -> P::Output<Option<&'a str>> {
P::to_output(crate::tryblock!({
self.node.properties()?.find(alias)?.map(|p| p.as_value().map_err(Into::into)).transpose()
}))
}
pub fn resolve(self, alias: &str) -> P::Output<Option<Node<'a, P>>> {
P::to_output(crate::tryblock!({
let Some(path) = Aliases::<(_, NoPanic)> { node: self.node }.resolve_name(alias)? else {
return Ok(None);
};
self.node.make_root::<P::Parser>()?.find_node(path).map(|r| r.map(|n| n.alt()))
}))
}
pub fn iter(self) -> P::Output<AllAliasesIter<'a, P>> {
P::to_output(crate::tryblock!({ Ok(AllAliasesIter { properties: self.node.properties()?.iter() }) }))
}
}
impl<'a, P: ParserWithMode<'a>> AsNode<'a, P> for Aliases<'a, P> {
fn as_node(&self) -> Node<'a, P> {
self.node.alt()
}
}
#[allow(missing_docs)]
pub struct AllAliasesIter<'a, P: ParserWithMode<'a>> {
properties: NodePropertiesIter<'a, FallibleParser<'a, P>>,
}
impl<'a, P> Iterator for AllAliasesIter<'a, P>
where
P: ParserWithMode<'a>,
{
type Item = P::Output<(&'a str, &'a str)>;
#[track_caller]
fn next(&mut self) -> Option<Self::Item> {
Some(P::to_output(match self.properties.next() {
Some(Ok(prop)) => crate::tryblock!({ Ok((prop.name, prop.as_value::<&'a str>()?)) }),
Some(Err(e)) => Err(e),
None => return None,
}))
}
}