Skip to main content

syn_sem/semantic/tree/
node.rs

1use super::{item::ItemIndex, PathId};
2use smallvec::SmallVec;
3use std::{cmp, fmt, iter, mem, ops};
4
5#[derive(Debug, Clone)]
6pub struct Node<T> {
7    pub(crate) items: SmallVec<[T; 1]>,
8    pub(crate) parent: NodeIndex,
9    pub(crate) children: Vec<(String, NodeIndex)>, // TODO: String -> Interned
10}
11
12impl<T> Node<T> {
13    pub fn iter(&self) -> NodeIter<'_, T> {
14        NodeIter::new(&self.items)
15    }
16
17    pub fn iter_mut(&mut self) -> NodeIterMut<'_, T> {
18        NodeIterMut::new(&mut self.items)
19    }
20
21    pub(crate) fn push(&mut self, item: T) -> ItemIndex {
22        self.items.push(item);
23        ItemIndex(self.items.len() - 1)
24    }
25}
26
27impl<T: Default> Node<T> {
28    /// # Panics
29    ///
30    /// Panics if the given index is out of bounds.
31    pub(crate) fn take(&mut self, ii: ItemIndex) -> T {
32        mem::take(&mut self.items[ii.0])
33    }
34}
35
36#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
37pub struct NodeIndex(pub(crate) usize);
38
39impl NodeIndex {
40    pub fn to_path_id<I: Into<ItemIndex>>(self, ii: I) -> PathId {
41        PathId {
42            ni: self,
43            ii: ii.into(),
44        }
45    }
46}
47
48impl From<usize> for NodeIndex {
49    fn from(value: usize) -> Self {
50        Self(value)
51    }
52}
53
54impl fmt::Display for NodeIndex {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        self.0.fmt(f)
57    }
58}
59
60impl fmt::Debug for NodeIndex {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        self.0.fmt(f)
63    }
64}
65
66impl PartialEq<usize> for NodeIndex {
67    fn eq(&self, other: &usize) -> bool {
68        self.0.eq(other)
69    }
70}
71
72impl PartialOrd<usize> for NodeIndex {
73    fn partial_cmp(&self, other: &usize) -> Option<cmp::Ordering> {
74        self.0.partial_cmp(other)
75    }
76}
77
78impl ops::Add<usize> for NodeIndex {
79    type Output = Self;
80
81    fn add(self, rhs: usize) -> Self::Output {
82        Self(self.0 + rhs)
83    }
84}
85
86impl ops::AddAssign<usize> for NodeIndex {
87    fn add_assign(&mut self, rhs: usize) {
88        self.0 += rhs;
89    }
90}
91
92impl ops::Sub<usize> for NodeIndex {
93    type Output = Self;
94
95    fn sub(self, rhs: usize) -> Self::Output {
96        Self(self.0 - rhs)
97    }
98}
99
100impl<T> ops::Index<NodeIndex> for [Node<T>] {
101    type Output = Node<T>;
102
103    fn index(&self, index: NodeIndex) -> &Self::Output {
104        &self[index.0]
105    }
106}
107
108impl<T> ops::IndexMut<NodeIndex> for [Node<T>] {
109    fn index_mut(&mut self, index: NodeIndex) -> &mut Self::Output {
110        &mut self[index.0]
111    }
112}
113
114impl<T> ops::Index<NodeIndex> for Vec<Node<T>> {
115    type Output = Node<T>;
116
117    fn index(&self, index: NodeIndex) -> &Self::Output {
118        &self.as_slice()[index]
119    }
120}
121
122impl<T> ops::IndexMut<NodeIndex> for Vec<Node<T>> {
123    fn index_mut(&mut self, index: NodeIndex) -> &mut Self::Output {
124        &mut self.as_mut_slice()[index]
125    }
126}
127
128/// An iterator traversing a node's items and yielding pairs of item index and reference to an
129/// [`Item`].
130pub struct NodeIter<'a, T> {
131    items: &'a [T],
132    ii: usize,
133}
134
135impl<'a, T> NodeIter<'a, T> {
136    pub(crate) const fn new(items: &'a [T]) -> Self {
137        Self { items, ii: 0 }
138    }
139
140    pub fn empty() -> Self {
141        Self { items: &[], ii: 0 }
142    }
143}
144
145impl<'a, T> Clone for NodeIter<'a, T> {
146    fn clone(&self) -> Self {
147        Self {
148            items: self.items,
149            ii: self.ii,
150        }
151    }
152}
153
154impl<'a, T> Iterator for NodeIter<'a, T> {
155    type Item = (ItemIndex, &'a T);
156
157    fn next(&mut self) -> Option<Self::Item> {
158        if let Some(item) = self.items.get(self.ii) {
159            let item = (ItemIndex(self.ii), item);
160            self.ii += 1;
161            Some(item)
162        } else {
163            None
164        }
165    }
166}
167
168impl<T> iter::FusedIterator for NodeIter<'_, T> {}
169
170/// An iterator traversing a node's items and yielding pairs of item index and mutable reference to
171/// an [`Item`].
172pub struct NodeIterMut<'a, T> {
173    items: &'a mut [T],
174    ii: usize,
175}
176
177impl<'a, T> NodeIterMut<'a, T> {
178    pub(crate) fn new(items: &'a mut [T]) -> Self {
179        Self { items, ii: 0 }
180    }
181
182    pub fn empty() -> Self {
183        Self {
184            items: &mut [],
185            ii: 0,
186        }
187    }
188}
189
190impl<'a, T> Iterator for NodeIterMut<'a, T> {
191    type Item = (ItemIndex, &'a mut T);
192
193    fn next(&mut self) -> Option<Self::Item> {
194        match mem::take(&mut self.items) {
195            [] => None,
196            [head, tail @ ..] => {
197                let item = (ItemIndex(self.ii), head);
198
199                self.items = tail;
200                self.ii += 1;
201
202                Some(item)
203            }
204        }
205    }
206}
207
208impl<T> iter::FusedIterator for NodeIterMut<'_, T> {}