1use crate::Language;
8use std::{
9 fmt,
10 hash::{Hash, Hasher},
11};
12
13pub enum GreenTree<'a, L: Language> {
18 Node(&'a GreenNode<'a, L>),
20 Leaf(GreenLeaf<L>),
22}
23
24impl<'a, L: Language> Clone for GreenTree<'a, L> {
26 fn clone(&self) -> Self {
27 *self
28 }
29}
30
31impl<'a, L: Language> Copy for GreenTree<'a, L> {}
32
33impl<'a, L: Language> fmt::Debug for GreenTree<'a, L> {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 match self {
36 Self::Node(node) => fmt::Debug::fmt(node, f),
37 Self::Leaf(leaf) => fmt::Debug::fmt(leaf, f),
38 }
39 }
40}
41
42impl<'a, L: Language> PartialEq for GreenTree<'a, L> {
43 fn eq(&self, other: &Self) -> bool {
44 match (self, other) {
45 (Self::Node(l0), Self::Node(r0)) => l0 == r0,
46 (Self::Leaf(l0), Self::Leaf(r0)) => l0 == r0,
47 _ => false,
48 }
49 }
50}
51
52impl<'a, L: Language> Eq for GreenTree<'a, L> {}
53
54impl<'a, L: Language> Hash for GreenTree<'a, L> {
55 fn hash<H: Hasher>(&self, state: &mut H) {
56 match self {
57 Self::Node(node) => node.hash(state),
58 Self::Leaf(leaf) => leaf.hash(state),
59 }
60 }
61}
62
63impl<'a, L: Language> GreenTree<'a, L> {
64 #[inline]
69 pub fn len(&self) -> u32 {
70 match self {
71 GreenTree::Node(n) => n.text_len,
72 GreenTree::Leaf(t) => t.length,
73 }
74 }
75
76 #[inline]
78 pub fn is_node(&self) -> bool {
79 matches!(self, Self::Node(_))
80 }
81
82 #[inline]
84 pub fn is_leaf(&self) -> bool {
85 matches!(self, Self::Leaf(_))
86 }
87
88 #[inline]
90 pub fn as_node(&self) -> Option<&'a GreenNode<'a, L>> {
91 match self {
92 Self::Node(n) => Some(n),
93 _ => None,
94 }
95 }
96
97 #[inline]
99 pub fn as_leaf(&self) -> Option<GreenLeaf<L>> {
100 match self {
101 Self::Leaf(l) => Some(*l),
102 _ => None,
103 }
104 }
105}
106
107pub struct GreenLeaf<L: Language> {
112 pub kind: L::TokenType,
114 pub length: u32,
116 pub metadata: Option<std::num::NonZeroU32>,
121}
122
123impl<L: Language> fmt::Debug for GreenLeaf<L> {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 f.debug_struct("GreenLeaf").field("kind", &self.kind).field("length", &self.length).field("metadata", &self.metadata).finish()
126 }
127}
128
129impl<L: Language> Hash for GreenLeaf<L> {
130 fn hash<H: Hasher>(&self, state: &mut H) {
131 self.kind.hash(state);
132 self.length.hash(state);
133 self.metadata.hash(state)
134 }
135}
136
137impl<L: Language> Clone for GreenLeaf<L> {
139 fn clone(&self) -> Self {
140 *self
141 }
142}
143
144impl<L: Language> Copy for GreenLeaf<L> {}
145
146impl<L: Language> PartialEq for GreenLeaf<L> {
147 fn eq(&self, other: &Self) -> bool {
148 self.kind == other.kind && self.length == other.length && self.metadata == other.metadata
149 }
150}
151
152impl<L: Language> Eq for GreenLeaf<L> {}
153
154impl<L: Language> GreenLeaf<L> {
155 #[inline]
162 pub fn new(kind: L::TokenType, len: u32) -> Self {
163 Self { kind, length: len, metadata: None }
164 }
165
166 #[inline]
174 pub fn with_metadata(kind: L::TokenType, len: u32, metadata: Option<std::num::NonZeroU32>) -> Self {
175 Self { kind, length: len, metadata }
176 }
177
178 #[inline]
180 pub fn kind(&self) -> L::TokenType {
181 self.kind
182 }
183
184 #[inline]
186 pub fn length(&self) -> u32 {
187 self.length
188 }
189}
190
191pub struct GreenNode<'a, L: Language> {
199 pub kind: L::ElementType,
201 pub text_len: u32,
203 pub children: &'a [GreenTree<'a, L>],
205}
206
207impl<'a, L: Language> Clone for GreenNode<'a, L> {
209 fn clone(&self) -> Self {
210 Self { kind: self.kind, text_len: self.text_len, children: self.children }
211 }
212}
213
214impl<'a, L: Language> PartialEq for GreenNode<'a, L> {
215 fn eq(&self, other: &Self) -> bool {
216 self.kind == other.kind && self.text_len == other.text_len && self.children == other.children
217 }
218}
219
220impl<'a, L: Language> Eq for GreenNode<'a, L> {}
221
222impl<'a, L: Language> fmt::Debug for GreenNode<'a, L> {
223 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224 f.debug_struct("GreenNode").field("kind", &self.kind).field("children", &self.children).field("length", &self.text_len).finish()
225 }
226}
227
228impl<'a, L: Language> Hash for GreenNode<'a, L> {
229 fn hash<H: Hasher>(&self, state: &mut H) {
230 self.kind.hash(state);
231 self.children.hash(state)
232 }
233}
234
235impl<'a, L: Language> GreenNode<'a, L> {
236 pub fn new(kind: L::ElementType, children: &'a [GreenTree<'a, L>]) -> Self {
246 let len: u32 = children.iter().map(|c| c.len()).sum();
247 Self { kind, text_len: len, children }
248 }
249
250 #[inline]
252 pub fn kind(&self) -> L::ElementType {
253 self.kind
254 }
255
256 #[inline]
258 pub fn text_len(&self) -> u32 {
259 self.text_len
260 }
261
262 #[inline]
264 pub fn children(&self) -> &'a [GreenTree<'a, L>] {
265 self.children
266 }
267
268 #[inline]
272 pub fn child_at(&self, index: usize) -> Option<&'a GreenTree<'a, L>> {
273 self.children.get(index)
274 }
275
276 #[inline]
278 pub fn has_children(&self) -> bool {
279 !self.children.is_empty()
280 }
281
282 #[inline]
284 pub fn children_count(&self) -> usize {
285 self.children.len()
286 }
287}