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