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