1
use pest::Parser as PestParser;
2
use pest::RuleType;
3
use pest::Span;
4
use pest::error::Error;
5
use pest::error::ErrorVariant;
6
use pest::iterators::Pair;
7
use pest::iterators::Pairs;
8

            
9
use crate::Parser;
10

            
11
/// A node of the parse tree.
12
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13
pub struct Node<'input, Rule: RuleType, Data> {
14
    pair: Pair<'input, Rule>,
15
    user_data: Data,
16
}
17

            
18
/// Iterator over [`Node`]s. It is created by [`Node::children`] or [`Parser::parse`].
19
///
20
/// [`Node`]: struct.Node.html
21
/// [`Node::children`]: struct.Node.html#method.children
22
/// [`Parser::parse`]: trait.Parser.html#method.parse
23
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24
pub struct Nodes<'input, Rule: RuleType, Data> {
25
    pairs: Pairs<'input, Rule>,
26
    pub(crate) span: Span<'input>,
27
    user_data: Data,
28
}
29

            
30
impl<'i, R: RuleType> Node<'i, R, ()> {
31
    #[doc(hidden)]
32
644823
    pub fn new(pair: Pair<'i, R>) -> Self {
33
644823
        Node { pair, user_data: () }
34
644823
    }
35
}
36
impl<'i, R: RuleType, D> Node<'i, R, D> {
37
    #[doc(hidden)]
38
946998
    pub fn new_with_user_data(pair: Pair<'i, R>, user_data: D) -> Self {
39
946998
        Node { pair, user_data }
40
946998
    }
41

            
42
605487
    pub fn as_str(&self) -> &'i str {
43
605487
        self.pair.as_str()
44
605487
    }
45

            
46
1056370
    pub fn as_span(&self) -> Span<'i> {
47
1056370
        self.pair.as_span()
48
1056370
    }
49

            
50
4713006
    pub fn as_rule(&self) -> R {
51
4713006
        self.pair.as_rule()
52
4713006
    }
53

            
54
    #[doc(hidden)]
55
1530568
    pub fn as_aliased_rule<C>(&self) -> C::AliasedRule
56
1530568
    where
57
1530568
        C: Parser<Rule = R>,
58
1530568
        <C as Parser>::Parser: PestParser<R>,
59
    {
60
1530568
        C::rule_alias(self.as_rule())
61
1530568
    }
62

            
63
    /// Returns an iterator over the children of this node
64
980008
    pub fn into_children(self) -> Nodes<'i, R, D> {
65
980008
        let span = self.as_span();
66
980008
        Nodes {
67
980008
            pairs: self.pair.into_inner(),
68
980008
            span,
69
980008
            user_data: self.user_data,
70
980008
        }
71
980008
    }
72
    /// Returns an iterator over the children of this node
73
453535
    pub fn children(&self) -> Nodes<'i, R, D>
74
453535
    where
75
453535
        D: Clone,
76
    {
77
453535
        self.clone().into_children()
78
453535
    }
79

            
80
    /// Create an error that points to the span of the node.
81
    pub fn error<S: ToString>(&self, message: S) -> Error<R> {
82
        Error::new_from_span(
83
            ErrorVariant::CustomError {
84
                message: message.to_string(),
85
            },
86
            self.as_span(),
87
        )
88
    }
89

            
90
    pub fn user_data(&self) -> &D {
91
        &self.user_data
92
    }
93

            
94
    pub fn into_user_data(self) -> D {
95
        self.user_data
96
    }
97

            
98
3426
    pub fn as_pair(&self) -> &Pair<'i, R> {
99
3426
        &self.pair
100
3426
    }
101

            
102
    pub fn into_pair(self) -> Pair<'i, R> {
103
        self.pair
104
    }
105
}
106

            
107
impl<'i, R: RuleType, D> Nodes<'i, R, D> {
108
    /// `input` must be the _original_ input that `pairs` is pointing to.
109
    #[doc(hidden)]
110
802
    pub(crate) fn new(input: &'i str, pairs: Pairs<'i, R>, user_data: D) -> Self {
111
802
        let span = Span::new(input, 0, input.len()).unwrap();
112
802
        Nodes { pairs, span, user_data }
113
802
    }
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,
123
        )
124
    }
125

            
126
    /// Returns the only element if there is only one element.
127
    #[allow(clippy::result_large_err)]
128
    pub fn single(mut self) -> Result<Node<'i, R, D>, Error<R>> {
129
        match (self.pairs.next(), self.pairs.next()) {
130
            (Some(pair), None) => Ok(Node::new_with_user_data(pair, self.user_data)),
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!("Expected a single node, instead got: {node_rules:?}"),
142
                    },
143
                    self.span,
144
                ))
145
            }
146
        }
147
    }
148

            
149
    /// Construct a node with the provided pair, passing the user data along.
150
946998
    fn with_pair(&self, pair: Pair<'i, R>) -> Node<'i, R, D>
151
946998
    where
152
946998
        D: Clone,
153
    {
154
946998
        Node::new_with_user_data(pair, self.user_data.clone())
155
946998
    }
156

            
157
    pub fn user_data(&self) -> &D {
158
        &self.user_data
159
    }
160

            
161
    pub fn into_user_data(self) -> D {
162
        self.user_data
163
    }
164

            
165
452733
    pub fn as_pairs(&self) -> &Pairs<'i, R> {
166
452733
        &self.pairs
167
452733
    }
168

            
169
    pub fn into_pairs(self) -> Pairs<'i, R> {
170
        self.pairs
171
    }
172
}
173

            
174
impl<'i, R, D> Iterator for Nodes<'i, R, D>
175
where
176
    R: RuleType,
177
    D: Clone,
178
{
179
    type Item = Node<'i, R, D>;
180

            
181
1472213
    fn next(&mut self) -> Option<Self::Item> {
182
1472213
        let child_pair = self.pairs.next()?;
183
946998
        let child = self.with_pair(child_pair);
184
946998
        Some(child)
185
1472213
    }
186
}
187

            
188
impl<R, D> DoubleEndedIterator for Nodes<'_, R, D>
189
where
190
    R: RuleType,
191
    D: Clone,
192
{
193
    fn next_back(&mut self) -> Option<Self::Item> {
194
        let child_pair = self.pairs.next_back()?;
195
        let child = self.with_pair(child_pair);
196
        Some(child)
197
    }
198
}
199

            
200
impl<R: RuleType, D> std::fmt::Display for Node<'_, R, D> {
201
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
202
        self.pair.fmt(f)
203
    }
204
}
205

            
206
impl<R: RuleType, D> std::fmt::Display for Nodes<'_, R, D> {
207
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
208
        self.pairs.fmt(f)
209
    }
210
}