syn/
punctuated.rs

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")]
24use std::fmt::{self, Debug};
25#[cfg(feature = "extra-traits")]
26use std::hash::{Hash, Hasher};
27#[cfg(any(feature = "full", feature = "derive"))]
28use std::iter;
29use std::iter::FromIterator;
30use std::ops::{Index, IndexMut};
31use std::option;
32use std::slice;
33use std::vec;
34
35use crate::drops::{NoDrop, TrivialDrop};
36#[cfg(feature = "parsing")]
37use crate::parse::{Parse, ParseStream, Result};
38#[cfg(feature = "parsing")]
39use 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
47pub struct Punctuated<T, P> {
48    inner: Vec<(T, P)>,
49    last: Option<Box<T>>,
50}
51
52impl<T, P> Punctuated<T, P> {
53    /// Creates an empty punctuated sequence.
54    #[cfg(not(syn_no_const_vec_new))]
55    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)]
64    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.
73    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`.
81    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.
86    pub fn first(&self) -> Option<&T> {
87        self.iter().next()
88    }
89
90    /// Mutably borrows the first element in this sequence.
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.
96    pub fn last(&self) -> Option<&T> {
97        self.iter().next_back()
98    }
99
100    /// Mutably borrows the last element in this sequence.
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`.
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`.
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.
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.
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.
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.
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.
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.
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.
203    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()`.
211    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`.
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.
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.
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")))]
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")))]
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")))]
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")))]
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")))]
372impl<T, P> Clone for Punctuated<T, P>
373where
374    T: Clone,
375    P: Clone,
376{
377    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")))]
387impl<T, P> Eq for Punctuated<T, P>
388where
389    T: Eq,
390    P: Eq,
391{
392}
393
394#[cfg(feature = "extra-traits")]
395#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
396impl<T, P> PartialEq for Punctuated<T, P>
397where
398    T: PartialEq,
399    P: PartialEq,
400{
401    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")))]
409impl<T, P> Hash for Punctuated<T, P>
410where
411    T: Hash,
412    P: Hash,
413{
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")))]
423impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
424    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
437impl<T, P> FromIterator<T> for Punctuated<T, P>
438where
439    P: Default,
440{
441    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
448impl<T, P> Extend<T> for Punctuated<T, P>
449where
450    P: Default,
451{
452    fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
453        for value in i {
454            self.push(value);
455        }
456    }
457}
458
459impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
460    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
467impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
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
490impl<T, P> IntoIterator for Punctuated<T, P> {
491    type Item = T;
492    type IntoIter = IntoIter<T>;
493
494    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
505impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
506    type Item = &'a T;
507    type IntoIter = Iter<'a, T>;
508
509    fn into_iter(self) -> Self::IntoIter {
510        Punctuated::iter(self)
511    }
512}
513
514impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
515    type Item = &'a mut T;
516    type IntoIter = IterMut<'a, T>;
517
518    fn into_iter(self) -> Self::IntoIter {
519        Punctuated::iter_mut(self)
520    }
521}
522
523impl<T, P> Default for Punctuated<T, P> {
524    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
534pub struct Pairs<'a, T: 'a, P: 'a> {
535    inner: slice::Iter<'a, (T, P)>,
536    last: option::IntoIter<&'a T>,
537}
538
539impl<'a, T, P> Iterator for Pairs<'a, T, P> {
540    type Item = Pair<&'a T, &'a P>;
541
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
549    fn size_hint(&self) -> (usize, Option<usize>) {
550        (self.len(), Some(self.len()))
551    }
552}
553
554impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
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
563impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
564    fn len(&self) -> usize {
565        self.inner.len() + self.last.len()
566    }
567}
568
569// No Clone bound on T or P.
570impl<'a, T, P> Clone for Pairs<'a, T, P> {
571    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
584pub struct PairsMut<'a, T: 'a, P: 'a> {
585    inner: slice::IterMut<'a, (T, P)>,
586    last: option::IntoIter<&'a mut T>,
587}
588
589impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
590    type Item = Pair<&'a mut T, &'a mut P>;
591
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
599    fn size_hint(&self) -> (usize, Option<usize>) {
600        (self.len(), Some(self.len()))
601    }
602}
603
604impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
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
613impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
614    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
624pub struct IntoPairs<T, P> {
625    inner: vec::IntoIter<(T, P)>,
626    last: option::IntoIter<T>,
627}
628
629impl<T, P> Iterator for IntoPairs<T, P> {
630    type Item = Pair<T, P>;
631
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
639    fn size_hint(&self) -> (usize, Option<usize>) {
640        (self.len(), Some(self.len()))
641    }
642}
643
644impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
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
653impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
654    fn len(&self) -> usize {
655        self.inner.len() + self.last.len()
656    }
657}
658
659impl<T, P> Clone for IntoPairs<T, P>
660where
661    T: Clone,
662    P: Clone,
663{
664    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
677pub struct IntoIter<T> {
678    inner: vec::IntoIter<T>,
679}
680
681impl<T> Iterator for IntoIter<T> {
682    type Item = T;
683
684    fn next(&mut self) -> Option<Self::Item> {
685        self.inner.next()
686    }
687
688    fn size_hint(&self) -> (usize, Option<usize>) {
689        (self.len(), Some(self.len()))
690    }
691}
692
693impl<T> DoubleEndedIterator for IntoIter<T> {
694    fn next_back(&mut self) -> Option<Self::Item> {
695        self.inner.next_back()
696    }
697}
698
699impl<T> ExactSizeIterator for IntoIter<T> {
700    fn len(&self) -> usize {
701        self.inner.len()
702    }
703}
704
705impl<T> Clone for IntoIter<T>
706where
707    T: Clone,
708{
709    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
721pub 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
728trait IterTrait<'a, T: 'a>:
729    DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T>
730{
731    fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T, Item = &'a T> + 'a>>;
732}
733
734struct PrivateIter<'a, T: 'a, P: 'a> {
735    inner: slice::Iter<'a, (T, P)>,
736    last: option::IntoIter<&'a T>,
737}
738
739impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
740where
741    slice::Iter<'a, (T, P)>: TrivialDrop,
742    option::IntoIter<&'a T>: TrivialDrop,
743{
744}
745
746#[cfg(any(feature = "full", feature = "derive"))]
747pub(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.
754impl<'a, T> Clone for Iter<'a, T> {
755    fn clone(&self) -> Self {
756        Iter {
757            inner: self.inner.clone_box(),
758        }
759    }
760}
761
762impl<'a, T> Iterator for Iter<'a, T> {
763    type Item = &'a T;
764
765    fn next(&mut self) -> Option<Self::Item> {
766        self.inner.next()
767    }
768
769    fn size_hint(&self) -> (usize, Option<usize>) {
770        (self.len(), Some(self.len()))
771    }
772}
773
774impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
775    fn next_back(&mut self) -> Option<Self::Item> {
776        self.inner.next_back()
777    }
778}
779
780impl<'a, T> ExactSizeIterator for Iter<'a, T> {
781    fn len(&self) -> usize {
782        self.inner.len()
783    }
784}
785
786impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
787    type Item = &'a T;
788
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
797impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
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
805impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
806    fn len(&self) -> usize {
807        self.inner.len() + self.last.len()
808    }
809}
810
811// No Clone bound on T or P.
812impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
813    fn clone(&self) -> Self {
814        PrivateIter {
815            inner: self.inner.clone(),
816            last: self.last.clone(),
817        }
818    }
819}
820
821impl<'a, T, I> IterTrait<'a, T> for I
822where
823    T: 'a,
824    I: DoubleEndedIterator<Item = &'a T>
825        + ExactSizeIterator<Item = &'a T>
826        + Clone
827        + TrivialDrop
828        + 'a,
829{
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
840pub struct IterMut<'a, T: 'a> {
841    inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
842}
843
844trait IterMutTrait<'a, T: 'a>:
845    DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
846{
847}
848
849struct PrivateIterMut<'a, T: 'a, P: 'a> {
850    inner: slice::IterMut<'a, (T, P)>,
851    last: option::IntoIter<&'a mut T>,
852}
853
854impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
855where
856    slice::IterMut<'a, (T, P)>: TrivialDrop,
857    option::IntoIter<&'a mut T>: TrivialDrop,
858{
859}
860
861#[cfg(any(feature = "full", feature = "derive"))]
862pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
863    IterMut {
864        inner: Box::new(NoDrop::new(iter::empty())),
865    }
866}
867
868impl<'a, T> Iterator for IterMut<'a, T> {
869    type Item = &'a mut T;
870
871    fn next(&mut self) -> Option<Self::Item> {
872        self.inner.next()
873    }
874
875    fn size_hint(&self) -> (usize, Option<usize>) {
876        (self.len(), Some(self.len()))
877    }
878}
879
880impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
881    fn next_back(&mut self) -> Option<Self::Item> {
882        self.inner.next_back()
883    }
884}
885
886impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
887    fn len(&self) -> usize {
888        self.inner.len()
889    }
890}
891
892impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
893    type Item = &'a mut T;
894
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
903impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
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
911impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
912    fn len(&self) -> usize {
913        self.inner.len() + self.last.len()
914    }
915}
916
917impl<'a, T, I> IterMutTrait<'a, T> for I
918where
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
930pub enum Pair<T, P> {
931    Punctuated(T, P),
932    End(T),
933}
934
935impl<T, P> Pair<T, P> {
936    /// Extracts the syntax tree node from this punctuated pair, discarding the
937    /// following punctuation.
938    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.
945    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.
952    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.
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    /// ```
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.
994    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.
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")))]
1013impl<T, P> Clone for Pair<T, P>
1014where
1015    T: Clone,
1016    P: Clone,
1017{
1018    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
1026impl<T, P> Index<usize> for Punctuated<T, P> {
1027    type Output = T;
1028
1029    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
1041impl<T, P> IndexMut<usize> for Punctuated<T, P> {
1042    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")]
1055mod 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    {
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    {
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}