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#[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#[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 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 pub fn children(&self) -> Nodes<'i, R, D>
70 where
71 D: Clone,
72 {
73 self.clone().into_children()
74 }
75
76 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 #[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 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 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 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 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}