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