1use std::{
36 fmt::{Display, Formatter},
37 iter::{Flatten, FusedIterator, Map},
38};
39
40use crate::{
41 lexis::{Site, SiteSpan, TokenRef},
42 syntax::{AbstractNode, NodeRef, PolyRef, RefKind},
43 units::CompilationUnit,
44};
45
46#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
48pub enum Key<'a> {
49 Name(&'a str),
51
52 Index(usize),
54}
55
56impl<'a> Display for Key<'a> {
57 #[inline(always)]
58 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
59 match self {
60 Self::Name(key) => Display::fmt(key, formatter),
61 Self::Index(key) => Display::fmt(key, formatter),
62 }
63 }
64}
65
66impl<'a> From<&'a str> for Key<'a> {
67 #[inline(always)]
68 fn from(value: &'a str) -> Self {
69 Self::Name(value)
70 }
71}
72
73impl<'a> From<usize> for Key<'a> {
74 #[inline(always)]
75 fn from(value: usize) -> Self {
76 Self::Index(value)
77 }
78}
79
80#[derive(Clone, PartialEq, Eq, Hash, Debug)]
102pub enum Capture<'a> {
103 SingleNode(&'a NodeRef),
111
112 ManyNodes(&'a Vec<NodeRef>),
117
118 SingleToken(&'a TokenRef),
126
127 ManyTokens(&'a Vec<TokenRef>),
132}
133
134impl<'a> From<&'a NodeRef> for Capture<'a> {
135 #[inline(always)]
136 fn from(capture: &'a NodeRef) -> Self {
137 Self::SingleNode(capture)
138 }
139}
140
141impl<'a> From<&'a Vec<NodeRef>> for Capture<'a> {
142 #[inline(always)]
143 fn from(capture: &'a Vec<NodeRef>) -> Self {
144 Self::ManyNodes(capture)
145 }
146}
147
148impl<'a> From<&'a TokenRef> for Capture<'a> {
149 #[inline(always)]
150 fn from(capture: &'a TokenRef) -> Self {
151 Self::SingleToken(capture)
152 }
153}
154
155impl<'a> From<&'a Vec<TokenRef>> for Capture<'a> {
156 #[inline(always)]
157 fn from(capture: &'a Vec<TokenRef>) -> Self {
158 Self::ManyTokens(capture)
159 }
160}
161
162impl<'a> IntoIterator for Capture<'a> {
163 type Item = &'a dyn PolyRef;
164 type IntoIter = CaptureIntoIter<'a>;
165
166 #[inline(always)]
167 fn into_iter(self) -> Self::IntoIter {
168 CaptureIntoIter::new(self)
169 }
170}
171
172impl<'a> Capture<'a> {
173 #[inline(always)]
175 pub fn kind(&self) -> RefKind {
176 match self {
177 Capture::SingleNode(..) | Capture::ManyNodes(..) => RefKind::Node,
178 Capture::SingleToken(..) | Capture::ManyTokens(..) => RefKind::Token,
179 }
180 }
181
182 #[inline(always)]
184 pub fn is_single(&self) -> bool {
185 match self {
186 Capture::SingleNode(..) | Capture::SingleToken(..) => true,
187 Capture::ManyTokens(..) | Capture::ManyNodes(..) => false,
188 }
189 }
190
191 #[inline(always)]
193 pub fn is_many(&self) -> bool {
194 !self.is_single()
195 }
196
197 #[inline(always)]
200 pub fn len(&self) -> usize {
201 match self {
202 Capture::SingleNode(..) | Capture::SingleToken(..) => 1,
203 Capture::ManyNodes(capture) => capture.len(),
204 Capture::ManyTokens(capture) => capture.len(),
205 }
206 }
207
208 #[inline(always)]
210 pub fn is_empty(&self) -> bool {
211 match self {
212 Capture::SingleNode(..) | Capture::SingleToken(..) => false,
213 Capture::ManyNodes(capture) => capture.is_empty(),
214 Capture::ManyTokens(capture) => capture.is_empty(),
215 }
216 }
217
218 #[inline(always)]
224 pub fn get(&self, index: usize) -> Option<&'a dyn PolyRef> {
225 match self {
226 Capture::SingleNode(capture) if index == 0 => Some(*capture),
227 Capture::SingleToken(capture) if index == 0 => Some(*capture),
228 Capture::ManyNodes(capture) => capture.get(index).map(|capture| capture as _),
229 Capture::ManyTokens(capture) => capture.get(index).map(|capture| capture as _),
230 _ => None,
231 }
232 }
233
234 #[inline(always)]
236 pub fn first(&self) -> Option<&'a dyn PolyRef> {
237 match self {
238 Capture::SingleNode(capture) => Some(*capture),
239 Capture::ManyNodes(capture) => capture.first().map(|capture| capture as _),
240 Capture::SingleToken(capture) => Some(*capture),
241 Capture::ManyTokens(capture) => capture.first().map(|capture| capture as _),
242 }
243 }
244
245 #[inline(always)]
248 pub fn last(&self) -> Option<&'a dyn PolyRef> {
249 match self {
250 Capture::SingleNode(capture) => Some(*capture),
251 Capture::ManyNodes(capture) => capture.last().map(|capture| capture as _),
252 Capture::SingleToken(capture) => Some(*capture),
253 Capture::ManyTokens(capture) => capture.last().map(|capture| capture as _),
254 }
255 }
256
257 pub fn site_span(&self, unit: &impl CompilationUnit) -> Option<SiteSpan> {
265 let start_site = self.start(unit)?;
266 let end_site = self.end(unit)?;
267
268 Some(start_site..end_site)
269 }
270
271 pub fn start(&self, unit: &impl CompilationUnit) -> Option<Site> {
278 match self {
279 Capture::SingleNode(capture) => (*capture).deref(unit)?.start(unit),
280 Capture::ManyNodes(capture) => capture.first()?.deref(unit)?.start(unit),
281 Capture::SingleToken(capture) => Some(capture.chunk(unit)?.start()),
282 Capture::ManyTokens(capture) => Some(capture.first()?.chunk(unit)?.start()),
283 }
284 }
285
286 pub fn end(&self, unit: &impl CompilationUnit) -> Option<Site> {
293 match self {
294 Capture::SingleNode(capture) => (*capture).deref(unit)?.end(unit),
295 Capture::ManyNodes(capture) => capture.last()?.deref(unit)?.end(unit),
296 Capture::SingleToken(capture) => Some(capture.chunk(unit)?.end()),
297 Capture::ManyTokens(capture) => Some(capture.last()?.chunk(unit)?.end()),
298 }
299 }
300}
301
302pub struct CaptureIntoIter<'a> {
306 front: usize,
307 back: usize,
308 capture: Capture<'a>,
309}
310
311impl<'a> Iterator for CaptureIntoIter<'a> {
312 type Item = &'a dyn PolyRef;
313
314 #[inline(always)]
315 fn next(&mut self) -> Option<Self::Item> {
316 if self.front == self.back {
317 return None;
318 }
319
320 let index = self.front;
321
322 self.front += 1;
323
324 self.capture.get(index)
325 }
326
327 #[inline(always)]
328 fn size_hint(&self) -> (usize, Option<usize>) {
329 let remaining = self.back - self.front;
330 (remaining, Some(remaining))
331 }
332}
333
334impl<'a> DoubleEndedIterator for CaptureIntoIter<'a> {
335 #[inline(always)]
336 fn next_back(&mut self) -> Option<Self::Item> {
337 if self.front == self.back {
338 return None;
339 }
340
341 self.back -= 1;
342
343 self.capture.get(self.back)
344 }
345}
346
347impl<'a> ExactSizeIterator for CaptureIntoIter<'a> {}
348
349impl<'a> FusedIterator for CaptureIntoIter<'a> {}
350
351impl<'a> CaptureIntoIter<'a> {
352 #[inline(always)]
353 fn new(capture: Capture<'a>) -> Self {
354 Self {
355 front: 0,
356 back: capture.len(),
357 capture,
358 }
359 }
360}
361
362pub struct CapturesIter<'a, N: AbstractNode + ?Sized> {
367 front: usize,
368 back: usize,
369 node: &'a N,
370}
371
372impl<'a, N: AbstractNode + ?Sized> Iterator for CapturesIter<'a, N> {
373 type Item = Capture<'a>;
374
375 #[inline(always)]
376 fn next(&mut self) -> Option<Self::Item> {
377 if self.front == self.back {
378 return None;
379 }
380
381 let index = self.front;
382
383 self.front += 1;
384
385 self.node.capture(Key::Index(index))
386 }
387
388 #[inline(always)]
389 fn size_hint(&self) -> (usize, Option<usize>) {
390 let remaining = self.back - self.front;
391 (remaining, Some(remaining))
392 }
393}
394
395impl<'a, N: AbstractNode + ?Sized> DoubleEndedIterator for CapturesIter<'a, N> {
396 #[inline(always)]
397 fn next_back(&mut self) -> Option<Self::Item> {
398 if self.front == self.back {
399 return None;
400 }
401
402 self.back -= 1;
403
404 self.node.capture(Key::Index(self.back))
405 }
406}
407
408impl<'a, N: AbstractNode + ?Sized> ExactSizeIterator for CapturesIter<'a, N> {}
409
410impl<'a, N: AbstractNode + ?Sized> FusedIterator for CapturesIter<'a, N> {}
411
412impl<'a, N: AbstractNode + ?Sized> CapturesIter<'a, N> {
413 #[inline(always)]
414 pub(super) fn new(node: &'a N) -> Self {
415 Self {
416 front: 0,
417 back: node.captures_len(),
418 node,
419 }
420 }
421}
422
423#[repr(transparent)]
428pub struct ChildrenIter<'a, N: AbstractNode + ?Sized> {
429 inner: Flatten<Map<CapturesIter<'a, N>, fn(Capture) -> CaptureIntoIter>>,
430}
431
432impl<'a, N: AbstractNode + ?Sized> Iterator for ChildrenIter<'a, N> {
433 type Item = &'a dyn PolyRef;
434
435 #[inline(always)]
436 fn next(&mut self) -> Option<Self::Item> {
437 self.inner.next()
438 }
439}
440
441impl<'a, N: AbstractNode + ?Sized> DoubleEndedIterator for ChildrenIter<'a, N> {
442 #[inline(always)]
443 fn next_back(&mut self) -> Option<Self::Item> {
444 self.inner.next_back()
445 }
446}
447
448impl<'a, N: AbstractNode + ?Sized> FusedIterator for ChildrenIter<'a, N> {}
449
450impl<'a, N: AbstractNode + ?Sized> ChildrenIter<'a, N> {
451 #[inline(always)]
452 pub(super) fn new(node: &'a N) -> Self {
453 fn capture_into_iter(capture: Capture) -> CaptureIntoIter {
454 capture.into_iter()
455 }
456
457 Self {
458 inner: CapturesIter::new(node)
459 .map(capture_into_iter as _)
460 .flatten(),
461 }
462 }
463}