cairo_lang_syntax/node/
element_list.rs1use std::marker::PhantomData;
2use std::sync::Arc;
3
4use super::SyntaxGroup;
5use crate::node::{SyntaxNode, TypedSyntaxNode};
6
7#[derive(Clone, Debug, Eq, Hash, PartialEq)]
11pub struct ElementList<T: TypedSyntaxNode, const STEP: usize> {
12 pub node: SyntaxNode,
13 phantom: PhantomData<T>,
14}
15impl<T: TypedSyntaxNode, const STEP: usize> ElementList<T, STEP> {
16 pub fn new(node: SyntaxNode) -> Self {
17 Self { node, phantom: PhantomData {} }
18 }
19}
20impl<T: TypedSyntaxNode> ElementList<T, 1> {
21 pub fn elements_vec(&self, db: &dyn SyntaxGroup) -> Vec<T> {
22 self.elements(db).collect()
23 }
24 pub fn elements<'a>(
25 &self,
26 db: &'a dyn SyntaxGroup,
27 ) -> impl ExactSizeIterator<Item = T> + DoubleEndedIterator + 'a {
28 ElementListRawIter::new(self.node.get_children(db)).map(move |x| T::from_syntax_node(db, x))
29 }
30 pub fn has_tail(&self, _db: &dyn SyntaxGroup) -> bool {
31 false
32 }
33}
34impl<T: TypedSyntaxNode> ElementList<T, 2> {
35 pub fn elements_vec(&self, db: &dyn SyntaxGroup) -> Vec<T> {
36 self.elements(db).collect()
37 }
38 pub fn elements<'a>(
39 &self,
40 db: &'a dyn SyntaxGroup,
41 ) -> impl ExactSizeIterator<Item = T> + DoubleEndedIterator + 'a {
42 ElementListRawIter::new(self.node.get_children(db))
43 .step_by(2)
44 .map(move |x| T::from_syntax_node(db, x))
45 }
46 pub fn has_tail(&self, db: &dyn SyntaxGroup) -> bool {
47 !self.node.get_children(db).len().is_multiple_of(2)
48 }
49}
50
51struct ElementListRawIter {
53 _data: Arc<[SyntaxNode]>,
55 iter: std::slice::Iter<'static, SyntaxNode>,
57}
58
59impl ElementListRawIter {
60 fn new(data: Arc<[SyntaxNode]>) -> Self {
61 let ptr: *const [SyntaxNode] = Arc::as_ptr(&data);
64 let slice: &'static [SyntaxNode] = unsafe { std::mem::transmute(&*ptr) };
65 let iter = slice.iter();
66 Self { _data: data, iter }
67 }
68}
69
70impl Iterator for ElementListRawIter {
71 type Item = SyntaxNode;
72
73 fn next(&mut self) -> Option<Self::Item> {
74 self.iter.next().copied()
75 }
76 fn size_hint(&self) -> (usize, Option<usize>) {
77 self.iter.size_hint()
78 }
79}
80impl ExactSizeIterator for ElementListRawIter {
81 fn len(&self) -> usize {
82 self.iter.len()
83 }
84}
85impl DoubleEndedIterator for ElementListRawIter {
86 fn next_back(&mut self) -> Option<Self::Item> {
87 self.iter.next_back().copied()
88 }
89}