• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! A punctuated sequence of syntax tree nodes separated by punctuation.
2 //!
3 //! Lots of things in Rust are punctuated sequences.
4 //!
5 //! - The fields of a struct are `Punctuated<Field, Token![,]>`.
6 //! - The segments of a path are `Punctuated<PathSegment, Token![::]>`.
7 //! - The bounds on a generic parameter are `Punctuated<TypeParamBound,
8 //!   Token![+]>`.
9 //! - The arguments to a function call are `Punctuated<Expr, Token![,]>`.
10 //!
11 //! This module provides a common representation for these punctuated sequences
12 //! in the form of the [`Punctuated<T, P>`] type. We store a vector of pairs of
13 //! syntax tree node + punctuation, where every node in the sequence is followed
14 //! by punctuation except for possibly the final one.
15 //!
16 //! [`Punctuated<T, P>`]: Punctuated
17 //!
18 //! ```text
19 //! a_function_call(arg1, arg2, arg3);
20 //!                 ~~~~^ ~~~~^ ~~~~
21 //! ```
22 
23 #[cfg(feature = "extra-traits")]
24 use std::fmt::{self, Debug};
25 #[cfg(feature = "extra-traits")]
26 use std::hash::{Hash, Hasher};
27 #[cfg(any(feature = "full", feature = "derive"))]
28 use std::iter;
29 use std::iter::FromIterator;
30 use std::ops::{Index, IndexMut};
31 use std::option;
32 use std::slice;
33 use std::vec;
34 
35 use crate::drops::{NoDrop, TrivialDrop};
36 #[cfg(feature = "parsing")]
37 use crate::parse::{Parse, ParseStream, Result};
38 #[cfg(feature = "parsing")]
39 use crate::token::Token;
40 
41 /// A punctuated sequence of syntax tree nodes of type `T` separated by
42 /// punctuation of type `P`.
43 ///
44 /// Refer to the [module documentation] for details about punctuated sequences.
45 ///
46 /// [module documentation]: self
47 pub struct Punctuated<T, P> {
48     inner: Vec<(T, P)>,
49     last: Option<Box<T>>,
50 }
51 
52 impl<T, P> Punctuated<T, P> {
53     /// Creates an empty punctuated sequence.
54     #[cfg(not(syn_no_const_vec_new))]
new() -> Self55     pub const fn new() -> Self {
56         Punctuated {
57             inner: Vec::new(),
58             last: None,
59         }
60     }
61 
62     /// Creates an empty punctuated sequence.
63     #[cfg(syn_no_const_vec_new)]
new() -> Self64     pub fn new() -> Self {
65         Punctuated {
66             inner: Vec::new(),
67             last: None,
68         }
69     }
70 
71     /// Determines whether this punctuated sequence is empty, meaning it
72     /// contains no syntax tree nodes or punctuation.
is_empty(&self) -> bool73     pub fn is_empty(&self) -> bool {
74         self.inner.len() == 0 && self.last.is_none()
75     }
76 
77     /// Returns the number of syntax tree nodes in this punctuated sequence.
78     ///
79     /// This is the number of nodes of type `T`, not counting the punctuation of
80     /// type `P`.
len(&self) -> usize81     pub fn len(&self) -> usize {
82         self.inner.len() + if self.last.is_some() { 1 } else { 0 }
83     }
84 
85     /// Borrows the first element in this sequence.
first(&self) -> Option<&T>86     pub fn first(&self) -> Option<&T> {
87         self.iter().next()
88     }
89 
90     /// Mutably borrows the first element in this sequence.
first_mut(&mut self) -> Option<&mut T>91     pub fn first_mut(&mut self) -> Option<&mut T> {
92         self.iter_mut().next()
93     }
94 
95     /// Borrows the last element in this sequence.
last(&self) -> Option<&T>96     pub fn last(&self) -> Option<&T> {
97         self.iter().next_back()
98     }
99 
100     /// Mutably borrows the last element in this sequence.
last_mut(&mut self) -> Option<&mut T>101     pub fn last_mut(&mut self) -> Option<&mut T> {
102         self.iter_mut().next_back()
103     }
104 
105     /// Returns an iterator over borrowed syntax tree nodes of type `&T`.
iter(&self) -> Iter<T>106     pub fn iter(&self) -> Iter<T> {
107         Iter {
108             inner: Box::new(NoDrop::new(PrivateIter {
109                 inner: self.inner.iter(),
110                 last: self.last.as_ref().map(Box::as_ref).into_iter(),
111             })),
112         }
113     }
114 
115     /// Returns an iterator over mutably borrowed syntax tree nodes of type
116     /// `&mut T`.
iter_mut(&mut self) -> IterMut<T>117     pub fn iter_mut(&mut self) -> IterMut<T> {
118         IterMut {
119             inner: Box::new(NoDrop::new(PrivateIterMut {
120                 inner: self.inner.iter_mut(),
121                 last: self.last.as_mut().map(Box::as_mut).into_iter(),
122             })),
123         }
124     }
125 
126     /// Returns an iterator over the contents of this sequence as borrowed
127     /// punctuated pairs.
pairs(&self) -> Pairs<T, P>128     pub fn pairs(&self) -> Pairs<T, P> {
129         Pairs {
130             inner: self.inner.iter(),
131             last: self.last.as_ref().map(Box::as_ref).into_iter(),
132         }
133     }
134 
135     /// Returns an iterator over the contents of this sequence as mutably
136     /// borrowed punctuated pairs.
pairs_mut(&mut self) -> PairsMut<T, P>137     pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
138         PairsMut {
139             inner: self.inner.iter_mut(),
140             last: self.last.as_mut().map(Box::as_mut).into_iter(),
141         }
142     }
143 
144     /// Returns an iterator over the contents of this sequence as owned
145     /// punctuated pairs.
into_pairs(self) -> IntoPairs<T, P>146     pub fn into_pairs(self) -> IntoPairs<T, P> {
147         IntoPairs {
148             inner: self.inner.into_iter(),
149             last: self.last.map(|t| *t).into_iter(),
150         }
151     }
152 
153     /// Appends a syntax tree node onto the end of this punctuated sequence. The
154     /// sequence must previously have a trailing punctuation.
155     ///
156     /// Use [`push`] instead if the punctuated sequence may or may not already
157     /// have trailing punctuation.
158     ///
159     /// [`push`]: Punctuated::push
160     ///
161     /// # Panics
162     ///
163     /// Panics if the sequence does not already have a trailing punctuation when
164     /// this method is called.
push_value(&mut self, value: T)165     pub fn push_value(&mut self, value: T) {
166         assert!(
167             self.empty_or_trailing(),
168             "Punctuated::push_value: cannot push value if Punctuated is missing trailing punctuation",
169         );
170 
171         self.last = Some(Box::new(value));
172     }
173 
174     /// Appends a trailing punctuation onto the end of this punctuated sequence.
175     /// The sequence must be non-empty and must not already have trailing
176     /// punctuation.
177     ///
178     /// # Panics
179     ///
180     /// Panics if the sequence is empty or already has a trailing punctuation.
push_punct(&mut self, punctuation: P)181     pub fn push_punct(&mut self, punctuation: P) {
182         assert!(
183             self.last.is_some(),
184             "Punctuated::push_punct: cannot push punctuation if Punctuated is empty or already has trailing punctuation",
185         );
186 
187         let last = self.last.take().unwrap();
188         self.inner.push((*last, punctuation));
189     }
190 
191     /// Removes the last punctuated pair from this sequence, or `None` if the
192     /// sequence is empty.
pop(&mut self) -> Option<Pair<T, P>>193     pub fn pop(&mut self) -> Option<Pair<T, P>> {
194         if self.last.is_some() {
195             self.last.take().map(|t| Pair::End(*t))
196         } else {
197             self.inner.pop().map(|(t, p)| Pair::Punctuated(t, p))
198         }
199     }
200 
201     /// Determines whether this punctuated sequence ends with a trailing
202     /// punctuation.
trailing_punct(&self) -> bool203     pub fn trailing_punct(&self) -> bool {
204         self.last.is_none() && !self.is_empty()
205     }
206 
207     /// Returns true if either this `Punctuated` is empty, or it has a trailing
208     /// punctuation.
209     ///
210     /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
empty_or_trailing(&self) -> bool211     pub fn empty_or_trailing(&self) -> bool {
212         self.last.is_none()
213     }
214 
215     /// Appends a syntax tree node onto the end of this punctuated sequence.
216     ///
217     /// If there is not a trailing punctuation in this sequence when this method
218     /// is called, the default value of punctuation type `P` is inserted before
219     /// the given value of type `T`.
push(&mut self, value: T) where P: Default,220     pub fn push(&mut self, value: T)
221     where
222         P: Default,
223     {
224         if !self.empty_or_trailing() {
225             self.push_punct(Default::default());
226         }
227         self.push_value(value);
228     }
229 
230     /// Inserts an element at position `index`.
231     ///
232     /// # Panics
233     ///
234     /// Panics if `index` is greater than the number of elements previously in
235     /// this punctuated sequence.
insert(&mut self, index: usize, value: T) where P: Default,236     pub fn insert(&mut self, index: usize, value: T)
237     where
238         P: Default,
239     {
240         assert!(
241             index <= self.len(),
242             "Punctuated::insert: index out of range",
243         );
244 
245         if index == self.len() {
246             self.push(value);
247         } else {
248             self.inner.insert(index, (value, Default::default()));
249         }
250     }
251 
252     /// Clears the sequence of all values and punctuation, making it empty.
clear(&mut self)253     pub fn clear(&mut self) {
254         self.inner.clear();
255         self.last = None;
256     }
257 
258     /// Parses zero or more occurrences of `T` separated by punctuation of type
259     /// `P`, with optional trailing punctuation.
260     ///
261     /// Parsing continues until the end of this parse stream. The entire content
262     /// of this parse stream must consist of `T` and `P`.
263     ///
264     /// *This function is available only if Syn is built with the `"parsing"`
265     /// feature.*
266     #[cfg(feature = "parsing")]
267     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
parse_terminated(input: ParseStream) -> Result<Self> where T: Parse, P: Parse,268     pub fn parse_terminated(input: ParseStream) -> Result<Self>
269     where
270         T: Parse,
271         P: Parse,
272     {
273         Self::parse_terminated_with(input, T::parse)
274     }
275 
276     /// Parses zero or more occurrences of `T` using the given parse function,
277     /// separated by punctuation of type `P`, with optional trailing
278     /// punctuation.
279     ///
280     /// Like [`parse_terminated`], the entire content of this stream is expected
281     /// to be parsed.
282     ///
283     /// [`parse_terminated`]: Punctuated::parse_terminated
284     ///
285     /// *This function is available only if Syn is built with the `"parsing"`
286     /// feature.*
287     #[cfg(feature = "parsing")]
288     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
parse_terminated_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Parse,289     pub fn parse_terminated_with(
290         input: ParseStream,
291         parser: fn(ParseStream) -> Result<T>,
292     ) -> Result<Self>
293     where
294         P: Parse,
295     {
296         let mut punctuated = Punctuated::new();
297 
298         loop {
299             if input.is_empty() {
300                 break;
301             }
302             let value = parser(input)?;
303             punctuated.push_value(value);
304             if input.is_empty() {
305                 break;
306             }
307             let punct = input.parse()?;
308             punctuated.push_punct(punct);
309         }
310 
311         Ok(punctuated)
312     }
313 
314     /// Parses one or more occurrences of `T` separated by punctuation of type
315     /// `P`, not accepting trailing punctuation.
316     ///
317     /// Parsing continues as long as punctuation `P` is present at the head of
318     /// the stream. This method returns upon parsing a `T` and observing that it
319     /// is not followed by a `P`, even if there are remaining tokens in the
320     /// stream.
321     ///
322     /// *This function is available only if Syn is built with the `"parsing"`
323     /// feature.*
324     #[cfg(feature = "parsing")]
325     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
parse_separated_nonempty(input: ParseStream) -> Result<Self> where T: Parse, P: Token + Parse,326     pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
327     where
328         T: Parse,
329         P: Token + Parse,
330     {
331         Self::parse_separated_nonempty_with(input, T::parse)
332     }
333 
334     /// Parses one or more occurrences of `T` using the given parse function,
335     /// separated by punctuation of type `P`, not accepting trailing
336     /// punctuation.
337     ///
338     /// Like [`parse_separated_nonempty`], may complete early without parsing
339     /// the entire content of this stream.
340     ///
341     /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
342     ///
343     /// *This function is available only if Syn is built with the `"parsing"`
344     /// feature.*
345     #[cfg(feature = "parsing")]
346     #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
parse_separated_nonempty_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Token + Parse,347     pub fn parse_separated_nonempty_with(
348         input: ParseStream,
349         parser: fn(ParseStream) -> Result<T>,
350     ) -> Result<Self>
351     where
352         P: Token + Parse,
353     {
354         let mut punctuated = Punctuated::new();
355 
356         loop {
357             let value = parser(input)?;
358             punctuated.push_value(value);
359             if !P::peek(input.cursor()) {
360                 break;
361             }
362             let punct = input.parse()?;
363             punctuated.push_punct(punct);
364         }
365 
366         Ok(punctuated)
367     }
368 }
369 
370 #[cfg(feature = "clone-impls")]
371 #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
372 impl<T, P> Clone for Punctuated<T, P>
373 where
374     T: Clone,
375     P: Clone,
376 {
clone(&self) -> Self377     fn clone(&self) -> Self {
378         Punctuated {
379             inner: self.inner.clone(),
380             last: self.last.clone(),
381         }
382     }
383 }
384 
385 #[cfg(feature = "extra-traits")]
386 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
387 impl<T, P> Eq for Punctuated<T, P>
388 where
389     T: Eq,
390     P: Eq,
391 {
392 }
393 
394 #[cfg(feature = "extra-traits")]
395 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
396 impl<T, P> PartialEq for Punctuated<T, P>
397 where
398     T: PartialEq,
399     P: PartialEq,
400 {
eq(&self, other: &Self) -> bool401     fn eq(&self, other: &Self) -> bool {
402         let Punctuated { inner, last } = self;
403         *inner == other.inner && *last == other.last
404     }
405 }
406 
407 #[cfg(feature = "extra-traits")]
408 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
409 impl<T, P> Hash for Punctuated<T, P>
410 where
411     T: Hash,
412     P: Hash,
413 {
hash<H: Hasher>(&self, state: &mut H)414     fn hash<H: Hasher>(&self, state: &mut H) {
415         let Punctuated { inner, last } = self;
416         inner.hash(state);
417         last.hash(state);
418     }
419 }
420 
421 #[cfg(feature = "extra-traits")]
422 #[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
423 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result424     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
425         let mut list = f.debug_list();
426         for (t, p) in &self.inner {
427             list.entry(t);
428             list.entry(p);
429         }
430         if let Some(last) = &self.last {
431             list.entry(last);
432         }
433         list.finish()
434     }
435 }
436 
437 impl<T, P> FromIterator<T> for Punctuated<T, P>
438 where
439     P: Default,
440 {
from_iter<I: IntoIterator<Item = T>>(i: I) -> Self441     fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
442         let mut ret = Punctuated::new();
443         ret.extend(i);
444         ret
445     }
446 }
447 
448 impl<T, P> Extend<T> for Punctuated<T, P>
449 where
450     P: Default,
451 {
extend<I: IntoIterator<Item = T>>(&mut self, i: I)452     fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
453         for value in i {
454             self.push(value);
455         }
456     }
457 }
458 
459 impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self460     fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
461         let mut ret = Punctuated::new();
462         ret.extend(i);
463         ret
464     }
465 }
466 
467 impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I)468     fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
469         assert!(
470             self.empty_or_trailing(),
471             "Punctuated::extend: Punctuated is not empty or does not have a trailing punctuation",
472         );
473 
474         let mut nomore = false;
475         for pair in i {
476             if nomore {
477                 panic!("Punctuated extended with items after a Pair::End");
478             }
479             match pair {
480                 Pair::Punctuated(a, b) => self.inner.push((a, b)),
481                 Pair::End(a) => {
482                     self.last = Some(Box::new(a));
483                     nomore = true;
484                 }
485             }
486         }
487     }
488 }
489 
490 impl<T, P> IntoIterator for Punctuated<T, P> {
491     type Item = T;
492     type IntoIter = IntoIter<T>;
493 
into_iter(self) -> Self::IntoIter494     fn into_iter(self) -> Self::IntoIter {
495         let mut elements = Vec::with_capacity(self.len());
496         elements.extend(self.inner.into_iter().map(|pair| pair.0));
497         elements.extend(self.last.map(|t| *t));
498 
499         IntoIter {
500             inner: elements.into_iter(),
501         }
502     }
503 }
504 
505 impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
506     type Item = &'a T;
507     type IntoIter = Iter<'a, T>;
508 
into_iter(self) -> Self::IntoIter509     fn into_iter(self) -> Self::IntoIter {
510         Punctuated::iter(self)
511     }
512 }
513 
514 impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
515     type Item = &'a mut T;
516     type IntoIter = IterMut<'a, T>;
517 
into_iter(self) -> Self::IntoIter518     fn into_iter(self) -> Self::IntoIter {
519         Punctuated::iter_mut(self)
520     }
521 }
522 
523 impl<T, P> Default for Punctuated<T, P> {
default() -> Self524     fn default() -> Self {
525         Punctuated::new()
526     }
527 }
528 
529 /// An iterator over borrowed pairs of type `Pair<&T, &P>`.
530 ///
531 /// Refer to the [module documentation] for details about punctuated sequences.
532 ///
533 /// [module documentation]: self
534 pub struct Pairs<'a, T: 'a, P: 'a> {
535     inner: slice::Iter<'a, (T, P)>,
536     last: option::IntoIter<&'a T>,
537 }
538 
539 impl<'a, T, P> Iterator for Pairs<'a, T, P> {
540     type Item = Pair<&'a T, &'a P>;
541 
next(&mut self) -> Option<Self::Item>542     fn next(&mut self) -> Option<Self::Item> {
543         self.inner
544             .next()
545             .map(|(t, p)| Pair::Punctuated(t, p))
546             .or_else(|| self.last.next().map(Pair::End))
547     }
548 
size_hint(&self) -> (usize, Option<usize>)549     fn size_hint(&self) -> (usize, Option<usize>) {
550         (self.len(), Some(self.len()))
551     }
552 }
553 
554 impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>555     fn next_back(&mut self) -> Option<Self::Item> {
556         self.last
557             .next()
558             .map(Pair::End)
559             .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
560     }
561 }
562 
563 impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
len(&self) -> usize564     fn len(&self) -> usize {
565         self.inner.len() + self.last.len()
566     }
567 }
568 
569 // No Clone bound on T or P.
570 impl<'a, T, P> Clone for Pairs<'a, T, P> {
clone(&self) -> Self571     fn clone(&self) -> Self {
572         Pairs {
573             inner: self.inner.clone(),
574             last: self.last.clone(),
575         }
576     }
577 }
578 
579 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`.
580 ///
581 /// Refer to the [module documentation] for details about punctuated sequences.
582 ///
583 /// [module documentation]: self
584 pub struct PairsMut<'a, T: 'a, P: 'a> {
585     inner: slice::IterMut<'a, (T, P)>,
586     last: option::IntoIter<&'a mut T>,
587 }
588 
589 impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
590     type Item = Pair<&'a mut T, &'a mut P>;
591 
next(&mut self) -> Option<Self::Item>592     fn next(&mut self) -> Option<Self::Item> {
593         self.inner
594             .next()
595             .map(|(t, p)| Pair::Punctuated(t, p))
596             .or_else(|| self.last.next().map(Pair::End))
597     }
598 
size_hint(&self) -> (usize, Option<usize>)599     fn size_hint(&self) -> (usize, Option<usize>) {
600         (self.len(), Some(self.len()))
601     }
602 }
603 
604 impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>605     fn next_back(&mut self) -> Option<Self::Item> {
606         self.last
607             .next()
608             .map(Pair::End)
609             .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
610     }
611 }
612 
613 impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
len(&self) -> usize614     fn len(&self) -> usize {
615         self.inner.len() + self.last.len()
616     }
617 }
618 
619 /// An iterator over owned pairs of type `Pair<T, P>`.
620 ///
621 /// Refer to the [module documentation] for details about punctuated sequences.
622 ///
623 /// [module documentation]: self
624 pub struct IntoPairs<T, P> {
625     inner: vec::IntoIter<(T, P)>,
626     last: option::IntoIter<T>,
627 }
628 
629 impl<T, P> Iterator for IntoPairs<T, P> {
630     type Item = Pair<T, P>;
631 
next(&mut self) -> Option<Self::Item>632     fn next(&mut self) -> Option<Self::Item> {
633         self.inner
634             .next()
635             .map(|(t, p)| Pair::Punctuated(t, p))
636             .or_else(|| self.last.next().map(Pair::End))
637     }
638 
size_hint(&self) -> (usize, Option<usize>)639     fn size_hint(&self) -> (usize, Option<usize>) {
640         (self.len(), Some(self.len()))
641     }
642 }
643 
644 impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
next_back(&mut self) -> Option<Self::Item>645     fn next_back(&mut self) -> Option<Self::Item> {
646         self.last
647             .next()
648             .map(Pair::End)
649             .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
650     }
651 }
652 
653 impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
len(&self) -> usize654     fn len(&self) -> usize {
655         self.inner.len() + self.last.len()
656     }
657 }
658 
659 impl<T, P> Clone for IntoPairs<T, P>
660 where
661     T: Clone,
662     P: Clone,
663 {
clone(&self) -> Self664     fn clone(&self) -> Self {
665         IntoPairs {
666             inner: self.inner.clone(),
667             last: self.last.clone(),
668         }
669     }
670 }
671 
672 /// An iterator over owned values of type `T`.
673 ///
674 /// Refer to the [module documentation] for details about punctuated sequences.
675 ///
676 /// [module documentation]: self
677 pub struct IntoIter<T> {
678     inner: vec::IntoIter<T>,
679 }
680 
681 impl<T> Iterator for IntoIter<T> {
682     type Item = T;
683 
next(&mut self) -> Option<Self::Item>684     fn next(&mut self) -> Option<Self::Item> {
685         self.inner.next()
686     }
687 
size_hint(&self) -> (usize, Option<usize>)688     fn size_hint(&self) -> (usize, Option<usize>) {
689         (self.len(), Some(self.len()))
690     }
691 }
692 
693 impl<T> DoubleEndedIterator for IntoIter<T> {
next_back(&mut self) -> Option<Self::Item>694     fn next_back(&mut self) -> Option<Self::Item> {
695         self.inner.next_back()
696     }
697 }
698 
699 impl<T> ExactSizeIterator for IntoIter<T> {
len(&self) -> usize700     fn len(&self) -> usize {
701         self.inner.len()
702     }
703 }
704 
705 impl<T> Clone for IntoIter<T>
706 where
707     T: Clone,
708 {
clone(&self) -> Self709     fn clone(&self) -> Self {
710         IntoIter {
711             inner: self.inner.clone(),
712         }
713     }
714 }
715 
716 /// An iterator over borrowed values of type `&T`.
717 ///
718 /// Refer to the [module documentation] for details about punctuated sequences.
719 ///
720 /// [module documentation]: self
721 pub struct Iter<'a, T: 'a> {
722     // The `Item = &'a T` needs to be specified to support rustc 1.31 and older.
723     // On modern compilers we would be able to write just IterTrait<'a, T> where
724     // Item can be inferred unambiguously from the supertrait.
725     inner: Box<NoDrop<dyn IterTrait<'a, T, Item = &'a T> + 'a>>,
726 }
727 
728 trait IterTrait<'a, T: 'a>:
729     DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T>
730 {
clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T, Item = &'a T> + 'a>>731     fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T, Item = &'a T> + 'a>>;
732 }
733 
734 struct PrivateIter<'a, T: 'a, P: 'a> {
735     inner: slice::Iter<'a, (T, P)>,
736     last: option::IntoIter<&'a T>,
737 }
738 
739 impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
740 where
741     slice::Iter<'a, (T, P)>: TrivialDrop,
742     option::IntoIter<&'a T>: TrivialDrop,
743 {
744 }
745 
746 #[cfg(any(feature = "full", feature = "derive"))]
empty_punctuated_iter<'a, T>() -> Iter<'a, T>747 pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
748     Iter {
749         inner: Box::new(NoDrop::new(iter::empty())),
750     }
751 }
752 
753 // No Clone bound on T.
754 impl<'a, T> Clone for Iter<'a, T> {
clone(&self) -> Self755     fn clone(&self) -> Self {
756         Iter {
757             inner: self.inner.clone_box(),
758         }
759     }
760 }
761 
762 impl<'a, T> Iterator for Iter<'a, T> {
763     type Item = &'a T;
764 
next(&mut self) -> Option<Self::Item>765     fn next(&mut self) -> Option<Self::Item> {
766         self.inner.next()
767     }
768 
size_hint(&self) -> (usize, Option<usize>)769     fn size_hint(&self) -> (usize, Option<usize>) {
770         (self.len(), Some(self.len()))
771     }
772 }
773 
774 impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
next_back(&mut self) -> Option<Self::Item>775     fn next_back(&mut self) -> Option<Self::Item> {
776         self.inner.next_back()
777     }
778 }
779 
780 impl<'a, T> ExactSizeIterator for Iter<'a, T> {
len(&self) -> usize781     fn len(&self) -> usize {
782         self.inner.len()
783     }
784 }
785 
786 impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
787     type Item = &'a T;
788 
next(&mut self) -> Option<Self::Item>789     fn next(&mut self) -> Option<Self::Item> {
790         self.inner
791             .next()
792             .map(|pair| &pair.0)
793             .or_else(|| self.last.next())
794     }
795 }
796 
797 impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>798     fn next_back(&mut self) -> Option<Self::Item> {
799         self.last
800             .next()
801             .or_else(|| self.inner.next_back().map(|pair| &pair.0))
802     }
803 }
804 
805 impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
len(&self) -> usize806     fn len(&self) -> usize {
807         self.inner.len() + self.last.len()
808     }
809 }
810 
811 // No Clone bound on T or P.
812 impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
clone(&self) -> Self813     fn clone(&self) -> Self {
814         PrivateIter {
815             inner: self.inner.clone(),
816             last: self.last.clone(),
817         }
818     }
819 }
820 
821 impl<'a, T, I> IterTrait<'a, T> for I
822 where
823     T: 'a,
824     I: DoubleEndedIterator<Item = &'a T>
825         + ExactSizeIterator<Item = &'a T>
826         + Clone
827         + TrivialDrop
828         + 'a,
829 {
clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T, Item = &'a T> + 'a>>830     fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T, Item = &'a T> + 'a>> {
831         Box::new(NoDrop::new(self.clone()))
832     }
833 }
834 
835 /// An iterator over mutably borrowed values of type `&mut T`.
836 ///
837 /// Refer to the [module documentation] for details about punctuated sequences.
838 ///
839 /// [module documentation]: self
840 pub struct IterMut<'a, T: 'a> {
841     inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
842 }
843 
844 trait IterMutTrait<'a, T: 'a>:
845     DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
846 {
847 }
848 
849 struct PrivateIterMut<'a, T: 'a, P: 'a> {
850     inner: slice::IterMut<'a, (T, P)>,
851     last: option::IntoIter<&'a mut T>,
852 }
853 
854 impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
855 where
856     slice::IterMut<'a, (T, P)>: TrivialDrop,
857     option::IntoIter<&'a mut T>: TrivialDrop,
858 {
859 }
860 
861 #[cfg(any(feature = "full", feature = "derive"))]
empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T>862 pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
863     IterMut {
864         inner: Box::new(NoDrop::new(iter::empty())),
865     }
866 }
867 
868 impl<'a, T> Iterator for IterMut<'a, T> {
869     type Item = &'a mut T;
870 
next(&mut self) -> Option<Self::Item>871     fn next(&mut self) -> Option<Self::Item> {
872         self.inner.next()
873     }
874 
size_hint(&self) -> (usize, Option<usize>)875     fn size_hint(&self) -> (usize, Option<usize>) {
876         (self.len(), Some(self.len()))
877     }
878 }
879 
880 impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
next_back(&mut self) -> Option<Self::Item>881     fn next_back(&mut self) -> Option<Self::Item> {
882         self.inner.next_back()
883     }
884 }
885 
886 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
len(&self) -> usize887     fn len(&self) -> usize {
888         self.inner.len()
889     }
890 }
891 
892 impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
893     type Item = &'a mut T;
894 
next(&mut self) -> Option<Self::Item>895     fn next(&mut self) -> Option<Self::Item> {
896         self.inner
897             .next()
898             .map(|pair| &mut pair.0)
899             .or_else(|| self.last.next())
900     }
901 }
902 
903 impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>904     fn next_back(&mut self) -> Option<Self::Item> {
905         self.last
906             .next()
907             .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
908     }
909 }
910 
911 impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
len(&self) -> usize912     fn len(&self) -> usize {
913         self.inner.len() + self.last.len()
914     }
915 }
916 
917 impl<'a, T, I> IterMutTrait<'a, T> for I
918 where
919     T: 'a,
920     I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T> + 'a,
921 {
922 }
923 
924 /// A single syntax tree node of type `T` followed by its trailing punctuation
925 /// of type `P` if any.
926 ///
927 /// Refer to the [module documentation] for details about punctuated sequences.
928 ///
929 /// [module documentation]: self
930 pub enum Pair<T, P> {
931     Punctuated(T, P),
932     End(T),
933 }
934 
935 impl<T, P> Pair<T, P> {
936     /// Extracts the syntax tree node from this punctuated pair, discarding the
937     /// following punctuation.
into_value(self) -> T938     pub fn into_value(self) -> T {
939         match self {
940             Pair::Punctuated(t, _) | Pair::End(t) => t,
941         }
942     }
943 
944     /// Borrows the syntax tree node from this punctuated pair.
value(&self) -> &T945     pub fn value(&self) -> &T {
946         match self {
947             Pair::Punctuated(t, _) | Pair::End(t) => t,
948         }
949     }
950 
951     /// Mutably borrows the syntax tree node from this punctuated pair.
value_mut(&mut self) -> &mut T952     pub fn value_mut(&mut self) -> &mut T {
953         match self {
954             Pair::Punctuated(t, _) | Pair::End(t) => t,
955         }
956     }
957 
958     /// Borrows the punctuation from this punctuated pair, unless this pair is
959     /// the final one and there is no trailing punctuation.
punct(&self) -> Option<&P>960     pub fn punct(&self) -> Option<&P> {
961         match self {
962             Pair::Punctuated(_, p) => Some(p),
963             Pair::End(_) => None,
964         }
965     }
966 
967     /// Mutably borrows the punctuation from this punctuated pair, unless the
968     /// pair is the final one and there is no trailing punctuation.
969     ///
970     /// # Example
971     ///
972     /// ```
973     /// # use proc_macro2::Span;
974     /// # use syn::punctuated::Punctuated;
975     /// # use syn::{parse_quote, Token, TypeParamBound};
976     /// #
977     /// # let mut punctuated = Punctuated::<TypeParamBound, Token![+]>::new();
978     /// # let span = Span::call_site();
979     /// #
980     /// punctuated.insert(0, parse_quote!('lifetime));
981     /// if let Some(punct) = punctuated.pairs_mut().next().unwrap().punct_mut() {
982     ///     punct.span = span;
983     /// }
984     /// ```
punct_mut(&mut self) -> Option<&mut P>985     pub fn punct_mut(&mut self) -> Option<&mut P> {
986         match self {
987             Pair::Punctuated(_, p) => Some(p),
988             Pair::End(_) => None,
989         }
990     }
991 
992     /// Creates a punctuated pair out of a syntax tree node and an optional
993     /// following punctuation.
new(t: T, p: Option<P>) -> Self994     pub fn new(t: T, p: Option<P>) -> Self {
995         match p {
996             Some(p) => Pair::Punctuated(t, p),
997             None => Pair::End(t),
998         }
999     }
1000 
1001     /// Produces this punctuated pair as a tuple of syntax tree node and
1002     /// optional following punctuation.
into_tuple(self) -> (T, Option<P>)1003     pub fn into_tuple(self) -> (T, Option<P>) {
1004         match self {
1005             Pair::Punctuated(t, p) => (t, Some(p)),
1006             Pair::End(t) => (t, None),
1007         }
1008     }
1009 }
1010 
1011 #[cfg(feature = "clone-impls")]
1012 #[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
1013 impl<T, P> Clone for Pair<T, P>
1014 where
1015     T: Clone,
1016     P: Clone,
1017 {
clone(&self) -> Self1018     fn clone(&self) -> Self {
1019         match self {
1020             Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
1021             Pair::End(t) => Pair::End(t.clone()),
1022         }
1023     }
1024 }
1025 
1026 impl<T, P> Index<usize> for Punctuated<T, P> {
1027     type Output = T;
1028 
index(&self, index: usize) -> &Self::Output1029     fn index(&self, index: usize) -> &Self::Output {
1030         if index == self.len() - 1 {
1031             match &self.last {
1032                 Some(t) => t,
1033                 None => &self.inner[index].0,
1034             }
1035         } else {
1036             &self.inner[index].0
1037         }
1038     }
1039 }
1040 
1041 impl<T, P> IndexMut<usize> for Punctuated<T, P> {
index_mut(&mut self, index: usize) -> &mut Self::Output1042     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1043         if index == self.len() - 1 {
1044             match &mut self.last {
1045                 Some(t) => t,
1046                 None => &mut self.inner[index].0,
1047             }
1048         } else {
1049             &mut self.inner[index].0
1050         }
1051     }
1052 }
1053 
1054 #[cfg(feature = "printing")]
1055 mod printing {
1056     use super::*;
1057     use proc_macro2::TokenStream;
1058     use quote::{ToTokens, TokenStreamExt};
1059 
1060     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1061     impl<T, P> ToTokens for Punctuated<T, P>
1062     where
1063         T: ToTokens,
1064         P: ToTokens,
1065     {
to_tokens(&self, tokens: &mut TokenStream)1066         fn to_tokens(&self, tokens: &mut TokenStream) {
1067             tokens.append_all(self.pairs());
1068         }
1069     }
1070 
1071     #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
1072     impl<T, P> ToTokens for Pair<T, P>
1073     where
1074         T: ToTokens,
1075         P: ToTokens,
1076     {
to_tokens(&self, tokens: &mut TokenStream)1077         fn to_tokens(&self, tokens: &mut TokenStream) {
1078             match self {
1079                 Pair::Punctuated(a, b) => {
1080                     a.to_tokens(tokens);
1081                     b.to_tokens(tokens);
1082                 }
1083                 Pair::End(a) => a.to_tokens(tokens),
1084             }
1085         }
1086     }
1087 }
1088