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