1use std::{option, slice, vec};
4
5use crate::cst::Token;
6use crate::{Parse, ParseStream, Span, Spanned, TextRange, ToTokens, TokenParseError, TokenStream};
7
8type Comma = Token![,];
9type Semicolon = Token![;];
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Spanned)]
16pub struct Empty {
17 span: Span,
18}
19
20impl Empty {
21 pub fn new(span: Span) -> Self {
23 Self { span }
24 }
25}
26
27impl Parse for Empty {
28 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
29 let span = input
30 .peek()
31 .map(|token| empty_before(token.span()))
32 .unwrap_or_else(|| input.eof_span());
33 Ok(Self::new(span))
34 }
35}
36
37impl ToTokens for Empty {
38 fn to_tokens(&self, _output: &mut TokenStream) {}
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Spanned)]
43pub enum Pair<S, P = Comma> {
44 Punctuated(S, P),
45 End(S),
46}
47
48impl<S, P> Pair<S, P> {
49 pub fn value(&self) -> &S {
51 match self {
52 Self::Punctuated(value, _) | Self::End(value) => value,
53 }
54 }
55
56 pub fn into_tuple(self) -> (S, Option<P>) {
58 match self {
59 Self::Punctuated(value, punctuation) => (value, Some(punctuation)),
60 Self::End(value) => (value, None),
61 }
62 }
63}
64
65impl<S, P> Parse for Pair<S, P>
66where
67 S: Parse,
68 P: Parse,
69{
70 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
71 let value = S::parse(input)?;
72 let mut fork = input.fork();
73 match P::parse(&mut fork) {
74 Ok(punctuation) => {
75 input.advance_to(&fork);
76 Ok(Self::Punctuated(value, punctuation))
77 }
78 Err(_) => Ok(Self::End(value)),
79 }
80 }
81}
82
83impl<S: ToTokens, P: ToTokens> ToTokens for Pair<S, P> {
84 fn to_tokens(&self, output: &mut TokenStream) {
85 match self {
86 Self::Punctuated(value, punctuation) => {
87 value.to_tokens(output);
88 punctuation.to_tokens(output);
89 }
90 Self::End(value) => value.to_tokens(output),
91 }
92 }
93}
94
95#[macro_export]
103macro_rules! punct {
104 () => {
105 $crate::Punctuated::new()
106 };
107 (value $value:expr) => {
108 $crate::Punctuated::from_value($value)
109 };
110 (pairs $first:expr; $($punctuation:expr => $next:expr),+ $(,)?) => {{
111 let mut values = $crate::Punctuated::from_value($first);
112 $(values.push($punctuation, $next);)+
113 values
114 }};
115 ($value:ty) => {
116 $crate::Punctuated<$value>
117 };
118}
119
120#[derive(Debug, Clone, PartialEq, Eq, Spanned)]
137pub struct Punctuated<S> {
138 inner: Vec<(S, Comma)>,
139 last: Option<Box<S>>,
140}
141
142impl<S> Punctuated<S> {
143 pub const fn new() -> Self {
145 Self {
146 inner: Vec::new(),
147 last: None,
148 }
149 }
150
151 pub fn len(&self) -> usize {
153 self.inner.len() + usize::from(self.last.is_some())
154 }
155
156 pub fn is_empty(&self) -> bool {
158 self.inner.is_empty() && self.last.is_none()
159 }
160
161 pub fn from_value(value: S) -> Self {
163 Self {
164 inner: Vec::new(),
165 last: Some(Box::new(value)),
166 }
167 }
168
169 pub fn iter(&self) -> Iter<'_, S> {
171 Iter {
172 inner: self.pairs(),
173 }
174 }
175
176 pub fn iter_mut(&mut self) -> IterMut<'_, S> {
178 IterMut {
179 inner: self.pairs_mut(),
180 }
181 }
182
183 pub fn pairs(&self) -> Pairs<'_, S> {
185 Pairs {
186 inner: self.inner.iter(),
187 last: self.last.as_deref().into_iter(),
188 }
189 }
190
191 pub fn pairs_mut(&mut self) -> PairsMut<'_, S> {
193 PairsMut {
194 inner: self.inner.iter_mut(),
195 last: self.last.as_deref_mut().into_iter(),
196 }
197 }
198
199 pub fn into_pairs(self) -> IntoPairs<S> {
201 IntoPairs {
202 inner: self.inner.into_iter(),
203 last: self.last.into_iter(),
204 }
205 }
206
207 pub fn push(&mut self, punctuation: Comma, next: S) {
212 let previous = self
213 .last
214 .take()
215 .expect("cannot punctuate an empty sequence");
216 self.inner.push((*previous, punctuation));
217 self.last = Some(Box::new(next));
218 }
219
220 pub fn map<T>(self, mut map: impl FnMut(S) -> T) -> Punctuated<T> {
222 Punctuated {
223 inner: self
224 .inner
225 .into_iter()
226 .map(|(value, comma)| (map(value), comma))
227 .collect(),
228 last: self.last.map(|value| Box::new(map(*value))),
229 }
230 }
231}
232
233impl<S> Default for Punctuated<S> {
234 fn default() -> Self {
235 Self::new()
236 }
237}
238
239impl<S> FromIterator<S> for Punctuated<S> {
240 fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
241 let mut iter = iter.into_iter();
242 let Some(first) = iter.next() else {
243 return Self::new();
244 };
245 let mut values = Self::from_value(first);
246 for value in iter {
247 values.push(Token), value);
248 }
249 values
250 }
251}
252
253impl<S> Parse for Punctuated<S>
254where
255 S: Parse + From<Empty>,
256{
257 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
258 let mut values = Self::new();
259 if input.is_eof() {
260 return Ok(values);
261 }
262
263 let first = if input
264 .peek()
265 .is_some_and(<Comma as Token>::matches_token_tree)
266 {
267 S::from(Empty::new(empty_before(input.peek().unwrap().span())))
268 } else {
269 S::parse(input)?
270 };
271 values = Self::from_value(first);
272
273 while input
274 .peek()
275 .is_some_and(<Comma as Token>::matches_token_tree)
276 {
277 let punctuation = Comma::parse(input)?;
278 let next = if input.is_eof()
279 || input.peek().is_some_and(|token| {
280 <Comma as Token>::matches_token_tree(token)
281 || <Semicolon as Token>::matches_token_tree(token)
282 }) {
283 let span = input
284 .peek()
285 .map(|token| empty_before(token.span()))
286 .unwrap_or_else(|| input.eof_span());
287 S::from(Empty::new(span))
288 } else {
289 S::parse(input)?
290 };
291 values.push(punctuation, next);
292 }
293 Ok(values)
294 }
295}
296
297impl<S: ToTokens> ToTokens for Punctuated<S> {
298 fn to_tokens(&self, output: &mut TokenStream) {
299 for pair in self.pairs() {
300 match pair {
301 Pair::Punctuated(value, punctuation) => {
302 value.to_tokens(output);
303 punctuation.to_tokens(output);
304 }
305 Pair::End(value) => value.to_tokens(output),
306 }
307 }
308 }
309}
310
311impl<S> IntoIterator for Punctuated<S> {
312 type Item = S;
313 type IntoIter = IntoIter<S>;
314
315 fn into_iter(self) -> Self::IntoIter {
316 let mut values = Vec::with_capacity(self.len());
317 values.extend(self.inner.into_iter().map(|(value, _)| value));
318 values.extend(self.last.map(|value| *value));
319 IntoIter {
320 inner: values.into_iter(),
321 }
322 }
323}
324
325impl<'a, S> IntoIterator for &'a Punctuated<S> {
326 type Item = &'a S;
327 type IntoIter = Iter<'a, S>;
328
329 fn into_iter(self) -> Self::IntoIter {
330 self.iter()
331 }
332}
333
334impl<'a, S> IntoIterator for &'a mut Punctuated<S> {
335 type Item = &'a mut S;
336 type IntoIter = IterMut<'a, S>;
337
338 fn into_iter(self) -> Self::IntoIter {
339 self.iter_mut()
340 }
341}
342
343pub struct IntoIter<S> {
345 inner: vec::IntoIter<S>,
346}
347
348impl<S> Iterator for IntoIter<S> {
349 type Item = S;
350
351 fn next(&mut self) -> Option<Self::Item> {
352 self.inner.next()
353 }
354
355 fn size_hint(&self) -> (usize, Option<usize>) {
356 (self.inner.len(), Some(self.inner.len()))
357 }
358}
359
360impl<S> DoubleEndedIterator for IntoIter<S> {
361 fn next_back(&mut self) -> Option<Self::Item> {
362 self.inner.next_back()
363 }
364}
365
366impl<S> ExactSizeIterator for IntoIter<S> {}
367
368pub struct Iter<'a, S> {
370 inner: Pairs<'a, S>,
371}
372
373impl<'a, S> Iterator for Iter<'a, S> {
374 type Item = &'a S;
375
376 fn next(&mut self) -> Option<Self::Item> {
377 self.inner.next().map(|pair| pair.into_tuple().0)
378 }
379
380 fn size_hint(&self) -> (usize, Option<usize>) {
381 self.inner.size_hint()
382 }
383}
384
385impl<S> DoubleEndedIterator for Iter<'_, S> {
386 fn next_back(&mut self) -> Option<Self::Item> {
387 self.inner.next_back().map(|pair| pair.into_tuple().0)
388 }
389}
390
391impl<S> ExactSizeIterator for Iter<'_, S> {}
392
393pub struct IterMut<'a, S> {
395 inner: PairsMut<'a, S>,
396}
397
398impl<'a, S> Iterator for IterMut<'a, S> {
399 type Item = &'a mut S;
400
401 fn next(&mut self) -> Option<Self::Item> {
402 self.inner.next().map(|pair| pair.into_tuple().0)
403 }
404
405 fn size_hint(&self) -> (usize, Option<usize>) {
406 self.inner.size_hint()
407 }
408}
409
410impl<S> DoubleEndedIterator for IterMut<'_, S> {
411 fn next_back(&mut self) -> Option<Self::Item> {
412 self.inner.next_back().map(|pair| pair.into_tuple().0)
413 }
414}
415
416impl<S> ExactSizeIterator for IterMut<'_, S> {}
417
418pub struct Pairs<'a, S> {
420 inner: slice::Iter<'a, (S, Comma)>,
421 last: option::IntoIter<&'a S>,
422}
423
424impl<'a, S> Iterator for Pairs<'a, S> {
425 type Item = Pair<&'a S, &'a Comma>;
426
427 fn next(&mut self) -> Option<Self::Item> {
428 self.inner
429 .next()
430 .map(|(value, punctuation)| Pair::Punctuated(value, punctuation))
431 .or_else(|| self.last.next().map(Pair::End))
432 }
433
434 fn size_hint(&self) -> (usize, Option<usize>) {
435 let len = self.inner.len() + self.last.len();
436 (len, Some(len))
437 }
438}
439
440impl<S> DoubleEndedIterator for Pairs<'_, S> {
441 fn next_back(&mut self) -> Option<Self::Item> {
442 self.last.next().map(Pair::End).or_else(|| {
443 self.inner
444 .next_back()
445 .map(|(value, punctuation)| Pair::Punctuated(value, punctuation))
446 })
447 }
448}
449
450impl<S> ExactSizeIterator for Pairs<'_, S> {}
451
452pub struct PairsMut<'a, S> {
454 inner: slice::IterMut<'a, (S, Comma)>,
455 last: option::IntoIter<&'a mut S>,
456}
457
458impl<'a, S> Iterator for PairsMut<'a, S> {
459 type Item = Pair<&'a mut S, &'a mut Comma>;
460
461 fn next(&mut self) -> Option<Self::Item> {
462 self.inner
463 .next()
464 .map(|(value, punctuation)| Pair::Punctuated(value, punctuation))
465 .or_else(|| self.last.next().map(Pair::End))
466 }
467
468 fn size_hint(&self) -> (usize, Option<usize>) {
469 let len = self.inner.len() + self.last.len();
470 (len, Some(len))
471 }
472}
473
474impl<S> DoubleEndedIterator for PairsMut<'_, S> {
475 fn next_back(&mut self) -> Option<Self::Item> {
476 self.last.next().map(Pair::End).or_else(|| {
477 self.inner
478 .next_back()
479 .map(|(value, punctuation)| Pair::Punctuated(value, punctuation))
480 })
481 }
482}
483
484impl<S> ExactSizeIterator for PairsMut<'_, S> {}
485
486pub struct IntoPairs<S> {
488 inner: vec::IntoIter<(S, Comma)>,
489 last: option::IntoIter<Box<S>>,
490}
491
492impl<S> Iterator for IntoPairs<S> {
493 type Item = Pair<S>;
494
495 fn next(&mut self) -> Option<Self::Item> {
496 self.inner
497 .next()
498 .map(|(value, punctuation)| Pair::Punctuated(value, punctuation))
499 .or_else(|| self.last.next().map(|value| Pair::End(*value)))
500 }
501
502 fn size_hint(&self) -> (usize, Option<usize>) {
503 let len = self.inner.len() + self.last.len();
504 (len, Some(len))
505 }
506}
507
508impl<S> DoubleEndedIterator for IntoPairs<S> {
509 fn next_back(&mut self) -> Option<Self::Item> {
510 self.last.next().map(|value| Pair::End(*value)).or_else(|| {
511 self.inner
512 .next_back()
513 .map(|(value, punctuation)| Pair::Punctuated(value, punctuation))
514 })
515 }
516}
517
518impl<S> ExactSizeIterator for IntoPairs<S> {}
519
520fn empty_before(span: Span) -> Span {
521 span.source()
522 .ok()
523 .zip(span.start_point().ok())
524 .map(|(source, point)| Span::new(source, TextRange::from_point(point)))
525 .unwrap_or_else(Span::detached)
526}