1use std::slice::Iter;
2use std::vec::IntoIter;
3
4use serde::Deserialize;
5use serde::Serialize;
6
7use mago_span::HasSpan;
8use mago_span::Position;
9use mago_span::Span;
10use mago_token::Token;
11
12#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
18#[repr(transparent)]
19pub struct Sequence<T> {
20 pub nodes: Vec<T>,
21}
22
23#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
29pub struct TokenSeparatedSequence<T> {
30 pub nodes: Vec<T>,
31 pub tokens: Vec<Token>,
32}
33
34impl<T: HasSpan> Sequence<T> {
35 #[inline]
36 pub const fn new(inner: Vec<T>) -> Self {
37 Self { nodes: inner }
38 }
39
40 #[inline]
41 pub const fn empty() -> Self {
42 Self { nodes: vec![] }
43 }
44
45 #[inline]
46 pub fn len(&self) -> usize {
47 self.nodes.len()
48 }
49
50 #[inline]
51 pub fn is_empty(&self) -> bool {
52 self.nodes.is_empty()
53 }
54
55 #[inline]
56 #[must_use]
57 pub fn get(&self, index: usize) -> Option<&T> {
58 self.nodes.get(index)
59 }
60
61 #[inline]
62 #[must_use]
63 pub fn first(&self) -> Option<&T> {
64 self.nodes.first()
65 }
66
67 #[inline]
68 #[must_use]
69 pub fn first_span(&self) -> Option<Span> {
70 self.nodes.first().map(|node| node.span())
71 }
72
73 #[inline]
74 #[must_use]
75 pub fn last(&self) -> Option<&T> {
76 self.nodes.last()
77 }
78
79 #[inline]
80 #[must_use]
81 pub fn last_span(&self) -> Option<Span> {
82 self.nodes.last().map(|node| node.span())
83 }
84
85 #[inline]
86 #[must_use]
87 pub fn span(&self, from: Position) -> Span {
88 self.last_span().map_or(Span::new(from, from), |span| Span::new(from, span.end))
89 }
90
91 #[inline]
92 pub fn iter(&self) -> Iter<'_, T> {
93 self.nodes.iter()
94 }
95
96 #[inline]
97 #[must_use]
98 pub fn as_slice(&self) -> &[T] {
99 self.nodes.as_slice()
100 }
101}
102
103impl<T: HasSpan> TokenSeparatedSequence<T> {
104 #[inline]
105 #[must_use]
106 pub const fn new(inner: Vec<T>, tokens: Vec<Token>) -> Self {
107 Self { nodes: inner, tokens }
108 }
109
110 #[inline]
111 #[must_use]
112 pub const fn empty() -> Self {
113 Self { nodes: vec![], tokens: vec![] }
114 }
115
116 #[inline]
117 pub fn len(&self) -> usize {
118 self.nodes.len()
119 }
120
121 #[inline]
122 pub fn is_empty(&self) -> bool {
123 self.nodes.is_empty()
124 }
125
126 #[inline]
127 pub fn get(&self, index: usize) -> Option<&T> {
128 self.nodes.get(index)
129 }
130
131 #[inline]
132 #[must_use]
133 pub fn first(&self) -> Option<&T> {
134 self.nodes.first()
135 }
136
137 #[inline]
138 pub fn first_span(&self) -> Option<Span> {
139 match (self.tokens.first(), self.nodes.first()) {
140 (Some(token), Some(node)) => {
141 if token.span.end <= node.span().start { Some(token.span) } else { Some(node.span()) }
143 }
144 (Some(token), None) => Some(token.span),
145 (None, Some(node)) => Some(node.span()),
146 (None, None) => None,
147 }
148 }
149
150 #[inline]
151 pub fn last(&self) -> Option<&T> {
152 self.nodes.last()
153 }
154
155 #[inline]
156 pub fn last_span(&self) -> Option<Span> {
157 match (self.tokens.last(), self.nodes.last()) {
158 (Some(token), Some(node)) => {
159 if token.span.start >= node.span().end { Some(token.span) } else { Some(node.span()) }
161 }
162 (Some(token), None) => Some(token.span),
163 (None, Some(node)) => Some(node.span()),
164 (None, None) => None,
165 }
166 }
167
168 #[inline]
169 pub fn span(&self, from: Position) -> Span {
170 self.last_span().map_or(Span::new(from, from), |span| Span::new(from, span.end))
171 }
172
173 #[inline]
174 pub fn has_trailing_token(&self) -> bool {
175 self.tokens.last().is_some_and(|token| token.span.start >= self.last_span().unwrap().end)
176 }
177
178 #[inline]
179 pub fn get_trailing_token(&self) -> Option<&Token> {
180 self.tokens.last().filter(|token| token.span.start >= self.last_span().unwrap().end)
181 }
182
183 #[inline]
184 pub fn iter(&self) -> Iter<'_, T> {
185 self.nodes.iter()
186 }
187
188 #[inline]
192 pub fn iter_with_tokens(&self) -> impl Iterator<Item = (usize, &T, Option<&Token>)> {
193 self.nodes.iter().enumerate().map(move |(i, item)| {
194 let token = self.tokens.get(i);
195
196 (i, item, token)
197 })
198 }
199
200 #[inline]
201 pub fn as_slice(&self) -> &[T] {
202 self.nodes.as_slice()
203 }
204}
205
206impl<T: HasSpan> FromIterator<T> for Sequence<T> {
207 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
208 Self { nodes: iter.into_iter().collect() }
209 }
210}
211
212impl<T: HasSpan> IntoIterator for Sequence<T> {
213 type Item = T;
214 type IntoIter = IntoIter<Self::Item>;
215
216 fn into_iter(self) -> Self::IntoIter {
217 self.nodes.into_iter()
218 }
219}
220
221impl<T: HasSpan> IntoIterator for TokenSeparatedSequence<T> {
222 type Item = T;
223 type IntoIter = IntoIter<Self::Item>;
224
225 fn into_iter(self) -> Self::IntoIter {
226 self.nodes.into_iter()
227 }
228}
229
230impl<T: HasSpan> std::default::Default for Sequence<T> {
231 fn default() -> Self {
232 Sequence::new(Default::default())
233 }
234}
235
236impl<T: HasSpan> std::default::Default for TokenSeparatedSequence<T> {
237 fn default() -> Self {
238 TokenSeparatedSequence::new(Default::default(), Default::default())
239 }
240}