pest_consume/
node.rs

1use crate::Parser;
2use pest::error::{Error, ErrorVariant};
3use pest::iterators::{Pair, Pairs};
4use pest::prec_climber::PrecClimber;
5use pest::Parser as PestParser;
6use pest::{RuleType, Span};
7
8/// A node of the parse tree.
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct Node<'input, Rule: RuleType, Data> {
11    pair: Pair<'input, Rule>,
12    user_data: Data,
13}
14
15/// Iterator over [`Node`]s. It is created by [`Node::children`] or [`Parser::parse`].
16///
17/// [`Node`]: struct.Node.html
18/// [`Node::children`]: struct.Node.html#method.children
19/// [`Parser::parse`]: trait.Parser.html#method.parse
20#[derive(Debug, Clone, PartialEq, Eq, Hash)]
21pub struct Nodes<'input, Rule: RuleType, Data> {
22    pairs: Pairs<'input, Rule>,
23    span: Span<'input>,
24    user_data: Data,
25}
26
27impl<'i, R: RuleType> Node<'i, R, ()> {
28    #[doc(hidden)]
29    pub fn new(pair: Pair<'i, R>) -> Self {
30        Node {
31            pair,
32            user_data: (),
33        }
34    }
35}
36impl<'i, R: RuleType, D> Node<'i, R, D> {
37    #[doc(hidden)]
38    pub fn new_with_user_data(pair: Pair<'i, R>, user_data: D) -> Self {
39        Node { pair, user_data }
40    }
41    pub fn as_str(&self) -> &'i str {
42        self.pair.as_str()
43    }
44    pub fn as_span(&self) -> Span<'i> {
45        self.pair.as_span()
46    }
47    pub fn as_rule(&self) -> R {
48        self.pair.as_rule()
49    }
50    #[doc(hidden)]
51    pub fn as_aliased_rule<C>(&self) -> C::AliasedRule
52    where
53        C: Parser<Rule = R>,
54        <C as Parser>::Parser: PestParser<R>,
55    {
56        C::rule_alias(self.as_rule())
57    }
58
59    /// Returns an iterator over the children of this node
60    pub fn into_children(self) -> Nodes<'i, R, D> {
61        let span = self.as_span();
62        Nodes {
63            pairs: self.pair.into_inner(),
64            span,
65            user_data: self.user_data,
66        }
67    }
68    /// Returns an iterator over the children of this node
69    pub fn children(&self) -> Nodes<'i, R, D>
70    where
71        D: Clone,
72    {
73        self.clone().into_children()
74    }
75
76    /// Create an error that points to the span of the node.
77    pub fn error<S: ToString>(&self, message: S) -> Error<R> {
78        Error::new_from_span(
79            ErrorVariant::CustomError {
80                message: message.to_string(),
81            },
82            self.as_span(),
83        )
84    }
85
86    pub fn user_data(&self) -> &D {
87        &self.user_data
88    }
89    pub fn into_user_data(self) -> D {
90        self.user_data
91    }
92    pub fn as_pair(&self) -> &Pair<'i, R> {
93        &self.pair
94    }
95    pub fn into_pair(self) -> Pair<'i, R> {
96        self.pair
97    }
98}
99
100impl<'i, R: RuleType, D> Nodes<'i, R, D> {
101    /// `input` must be the _original_ input that `pairs` is pointing to.
102    #[doc(hidden)]
103    pub(crate) fn new(
104        input: &'i str,
105        pairs: Pairs<'i, R>,
106        user_data: D,
107    ) -> Self {
108        let span = Span::new(input, 0, input.len()).unwrap();
109        Nodes {
110            pairs,
111            span,
112            user_data,
113        }
114    }
115    /// Create an error that points to the initial span of the nodes.
116    /// Note that this span does not change as the iterator is consumed.
117    pub fn error<S: ToString>(&self, message: S) -> Error<R> {
118        Error::new_from_span(
119            ErrorVariant::CustomError {
120                message: message.to_string(),
121            },
122            self.span.clone(),
123        )
124    }
125    /// Returns the only element if there is only one element.
126    pub fn single(mut self) -> Result<Node<'i, R, D>, Error<R>> {
127        match (self.pairs.next(), self.pairs.next()) {
128            (Some(pair), None) => {
129                Ok(Node::new_with_user_data(pair, self.user_data))
130            }
131            (first, second) => {
132                let node_rules: Vec<_> = first
133                    .into_iter()
134                    .chain(second)
135                    .chain(self.pairs)
136                    .map(|p| p.as_rule())
137                    .collect();
138
139                Err(Error::new_from_span(
140                    ErrorVariant::CustomError {
141                        message: format!(
142                            "Expected a single node, instead got: {:?}",
143                            node_rules
144                        ),
145                    },
146                    self.span,
147                ))
148            }
149        }
150    }
151    #[doc(hidden)]
152    pub fn aliased_rules<C>(
153        &self,
154    ) -> std::iter::Map<
155        Pairs<'i, R>,
156        impl FnMut(Pair<'i, R>) -> <C as Parser>::AliasedRule,
157    >
158    where
159        C: Parser<Rule = R>,
160        <C as Parser>::Parser: PestParser<R>,
161    {
162        self.pairs.clone().map(|p| C::rule_alias(p.as_rule()))
163    }
164    /// Construct a node with the provided pair, passing the user data along.
165    fn with_pair(&self, pair: Pair<'i, R>) -> Node<'i, R, D>
166    where
167        D: Clone,
168    {
169        Node::new_with_user_data(pair, self.user_data.clone())
170    }
171    /// Performs the precedence climbing algorithm on the nodes.
172    pub fn prec_climb<T, E, F1, F2>(
173        self,
174        climber: &PrecClimber<R>,
175        mut primary: F1,
176        mut infix: F2,
177    ) -> Result<T, E>
178    where
179        D: Clone,
180        F1: FnMut(Node<'i, R, D>) -> Result<T, E>,
181        F2: FnMut(T, Node<'i, R, D>, T) -> Result<T, E>,
182    {
183        let user_data = self.user_data;
184        let with_pair = |p| Node::new_with_user_data(p, user_data.clone());
185        climber.climb(
186            self.pairs,
187            |p| primary(with_pair(p)),
188            |l, p, r| infix(l?, with_pair(p), r?),
189        )
190    }
191
192    pub fn user_data(&self) -> &D {
193        &self.user_data
194    }
195    pub fn into_user_data(self) -> D {
196        self.user_data
197    }
198    pub fn as_pairs(&self) -> &Pairs<'i, R> {
199        &self.pairs
200    }
201    pub fn into_pairs(self) -> Pairs<'i, R> {
202        self.pairs
203    }
204}
205
206impl<'i, R, D> Iterator for Nodes<'i, R, D>
207where
208    R: RuleType,
209    D: Clone,
210{
211    type Item = Node<'i, R, D>;
212
213    fn next(&mut self) -> Option<Self::Item> {
214        let child_pair = self.pairs.next()?;
215        let child = self.with_pair(child_pair);
216        Some(child)
217    }
218}
219
220impl<'i, R, D> DoubleEndedIterator for Nodes<'i, R, D>
221where
222    R: RuleType,
223    D: Clone,
224{
225    fn next_back(&mut self) -> Option<Self::Item> {
226        let child_pair = self.pairs.next_back()?;
227        let child = self.with_pair(child_pair);
228        Some(child)
229    }
230}
231
232impl<'i, R: RuleType, D> std::fmt::Display for Node<'i, R, D> {
233    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
234        self.pair.fmt(f)
235    }
236}
237
238impl<'i, R: RuleType, D> std::fmt::Display for Nodes<'i, R, D> {
239    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
240        self.pairs.fmt(f)
241    }
242}