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>`]: struct.Punctuated.html
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(any(feature = "full", feature = "derive"))]
26use std::iter;
27use std::iter::FromIterator;
28use std::ops::{Index, IndexMut};
29use std::option;
30use std::slice;
31use std::vec;
32
33#[cfg(feature = "parsing")]
34use crate::parse::{Parse, ParseStream, Result};
35#[cfg(feature = "parsing")]
36use crate::token::Token;
37
38/// A punctuated sequence of syntax tree nodes of type `T` separated by
39/// punctuation of type `P`.
40///
41/// Refer to the [module documentation] for details about punctuated sequences.
42///
43/// [module documentation]: self
44#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))]
45#[cfg_attr(feature = "clone-impls", derive(Clone))]
46pub struct Punctuated<T, P> {
47    inner: Vec<(T, P)>,
48    last: Option<Box<T>>,
49}
50
51impl<T, P> Punctuated<T, P> {
52    /// Creates an empty punctuated sequence.
53    pub fn new() -> Punctuated<T, P> {
54        Punctuated {
55            inner: Vec::new(),
56            last: None,
57        }
58    }
59
60    /// Determines whether this punctuated sequence is empty, meaning it
61    /// contains no syntax tree nodes or punctuation.
62    pub fn is_empty(&self) -> bool {
63        self.inner.len() == 0 && self.last.is_none()
64    }
65
66    /// Returns the number of syntax tree nodes in this punctuated sequence.
67    ///
68    /// This is the number of nodes of type `T`, not counting the punctuation of
69    /// type `P`.
70    pub fn len(&self) -> usize {
71        self.inner.len() + if self.last.is_some() { 1 } else { 0 }
72    }
73
74    /// Borrows the first element in this sequence.
75    pub fn first(&self) -> Option<&T> {
76        self.iter().next()
77    }
78
79    /// Borrows the last element in this sequence.
80    pub fn last(&self) -> Option<&T> {
81        if self.last.is_some() {
82            self.last.as_ref().map(Box::as_ref)
83        } else {
84            self.inner.last().map(|pair| &pair.0)
85        }
86    }
87
88    /// Mutably borrows the last element in this sequence.
89    pub fn last_mut(&mut self) -> Option<&mut T> {
90        if self.last.is_some() {
91            self.last.as_mut().map(Box::as_mut)
92        } else {
93            self.inner.last_mut().map(|pair| &mut pair.0)
94        }
95    }
96
97    /// Returns an iterator over borrowed syntax tree nodes of type `&T`.
98    pub fn iter(&self) -> Iter<T> {
99        Iter {
100            inner: Box::new(PrivateIter {
101                inner: self.inner.iter(),
102                last: self.last.as_ref().map(Box::as_ref).into_iter(),
103            }),
104        }
105    }
106
107    /// Returns an iterator over mutably borrowed syntax tree nodes of type
108    /// `&mut T`.
109    pub fn iter_mut(&mut self) -> IterMut<T> {
110        IterMut {
111            inner: Box::new(PrivateIterMut {
112                inner: self.inner.iter_mut(),
113                last: self.last.as_mut().map(Box::as_mut).into_iter(),
114            }),
115        }
116    }
117
118    /// Returns an iterator over the contents of this sequence as borrowed
119    /// punctuated pairs.
120    pub fn pairs(&self) -> Pairs<T, P> {
121        Pairs {
122            inner: self.inner.iter(),
123            last: self.last.as_ref().map(Box::as_ref).into_iter(),
124        }
125    }
126
127    /// Returns an iterator over the contents of this sequence as mutably
128    /// borrowed punctuated pairs.
129    pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
130        PairsMut {
131            inner: self.inner.iter_mut(),
132            last: self.last.as_mut().map(Box::as_mut).into_iter(),
133        }
134    }
135
136    /// Returns an iterator over the contents of this sequence as owned
137    /// punctuated pairs.
138    pub fn into_pairs(self) -> IntoPairs<T, P> {
139        IntoPairs {
140            inner: self.inner.into_iter(),
141            last: self.last.map(|t| *t).into_iter(),
142        }
143    }
144
145    /// Appends a syntax tree node onto the end of this punctuated sequence. The
146    /// sequence must previously have a trailing punctuation.
147    ///
148    /// Use [`push`] instead if the punctuated sequence may or may not already
149    /// have trailing punctuation.
150    ///
151    /// [`push`]: Punctuated::push
152    ///
153    /// # Panics
154    ///
155    /// Panics if the sequence does not already have a trailing punctuation when
156    /// this method is called.
157    pub fn push_value(&mut self, value: T) {
158        assert!(self.empty_or_trailing());
159        self.last = Some(Box::new(value));
160    }
161
162    /// Appends a trailing punctuation onto the end of this punctuated sequence.
163    /// The sequence must be non-empty and must not already have trailing
164    /// punctuation.
165    ///
166    /// # Panics
167    ///
168    /// Panics if the sequence is empty or already has a trailing punctuation.
169    pub fn push_punct(&mut self, punctuation: P) {
170        assert!(self.last.is_some());
171        let last = self.last.take().unwrap();
172        self.inner.push((*last, punctuation));
173    }
174
175    /// Removes the last punctuated pair from this sequence, or `None` if the
176    /// sequence is empty.
177    pub fn pop(&mut self) -> Option<Pair<T, P>> {
178        if self.last.is_some() {
179            self.last.take().map(|t| Pair::End(*t))
180        } else {
181            self.inner.pop().map(|(t, d)| Pair::Punctuated(t, d))
182        }
183    }
184
185    /// Determines whether this punctuated sequence ends with a trailing
186    /// punctuation.
187    pub fn trailing_punct(&self) -> bool {
188        self.last.is_none() && !self.is_empty()
189    }
190
191    /// Returns true if either this `Punctuated` is empty, or it has a trailing
192    /// punctuation.
193    ///
194    /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
195    pub fn empty_or_trailing(&self) -> bool {
196        self.last.is_none()
197    }
198
199    /// Appends a syntax tree node onto the end of this punctuated sequence.
200    ///
201    /// If there is not a trailing punctuation in this sequence when this method
202    /// is called, the default value of punctuation type `P` is inserted before
203    /// the given value of type `T`.
204    pub fn push(&mut self, value: T)
205    where
206        P: Default,
207    {
208        if !self.empty_or_trailing() {
209            self.push_punct(Default::default());
210        }
211        self.push_value(value);
212    }
213
214    /// Inserts an element at position `index`.
215    ///
216    /// # Panics
217    ///
218    /// Panics if `index` is greater than the number of elements previously in
219    /// this punctuated sequence.
220    pub fn insert(&mut self, index: usize, value: T)
221    where
222        P: Default,
223    {
224        assert!(index <= self.len());
225
226        if index == self.len() {
227            self.push(value);
228        } else {
229            self.inner.insert(index, (value, Default::default()));
230        }
231    }
232
233    /// Parses zero or more occurrences of `T` separated by punctuation of type
234    /// `P`, with optional trailing punctuation.
235    ///
236    /// Parsing continues until the end of this parse stream. The entire content
237    /// of this parse stream must consist of `T` and `P`.
238    ///
239    /// *This function is available if Syn is built with the `"parsing"`
240    /// feature.*
241    #[cfg(feature = "parsing")]
242    pub fn parse_terminated(input: ParseStream) -> Result<Self>
243    where
244        T: Parse,
245        P: Parse,
246    {
247        Self::parse_terminated_with(input, T::parse)
248    }
249
250    /// Parses zero or more occurrences of `T` using the given parse function,
251    /// separated by punctuation of type `P`, with optional trailing
252    /// punctuation.
253    ///
254    /// Like [`parse_terminated`], the entire content of this stream is expected
255    /// to be parsed.
256    ///
257    /// [`parse_terminated`]: Punctuated::parse_terminated
258    ///
259    /// *This function is available if Syn is built with the `"parsing"`
260    /// feature.*
261    #[cfg(feature = "parsing")]
262    pub fn parse_terminated_with(
263        input: ParseStream,
264        parser: fn(ParseStream) -> Result<T>,
265    ) -> Result<Self>
266    where
267        P: Parse,
268    {
269        let mut punctuated = Punctuated::new();
270
271        loop {
272            if input.is_empty() {
273                break;
274            }
275            let value = parser(input)?;
276            punctuated.push_value(value);
277            if input.is_empty() {
278                break;
279            }
280            let punct = input.parse()?;
281            punctuated.push_punct(punct);
282        }
283
284        Ok(punctuated)
285    }
286
287    /// Parses one or more occurrences of `T` separated by punctuation of type
288    /// `P`, not accepting trailing punctuation.
289    ///
290    /// Parsing continues as long as punctuation `P` is present at the head of
291    /// the stream. This method returns upon parsing a `T` and observing that it
292    /// is not followed by a `P`, even if there are remaining tokens in the
293    /// stream.
294    ///
295    /// *This function is available if Syn is built with the `"parsing"`
296    /// feature.*
297    #[cfg(feature = "parsing")]
298    pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
299    where
300        T: Parse,
301        P: Token + Parse,
302    {
303        Self::parse_separated_nonempty_with(input, T::parse)
304    }
305
306    /// Parses one or more occurrences of `T` using the given parse function,
307    /// separated by punctuation of type `P`, not accepting trailing
308    /// punctuation.
309    ///
310    /// Like [`parse_separated_nonempty`], may complete early without parsing
311    /// the entire content of this stream.
312    ///
313    /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
314    ///
315    /// *This function is available if Syn is built with the `"parsing"`
316    /// feature.*
317    #[cfg(feature = "parsing")]
318    pub fn parse_separated_nonempty_with(
319        input: ParseStream,
320        parser: fn(ParseStream) -> Result<T>,
321    ) -> Result<Self>
322    where
323        P: Token + Parse,
324    {
325        let mut punctuated = Punctuated::new();
326
327        loop {
328            let value = parser(input)?;
329            punctuated.push_value(value);
330            if !P::peek(input.cursor()) {
331                break;
332            }
333            let punct = input.parse()?;
334            punctuated.push_punct(punct);
335        }
336
337        Ok(punctuated)
338    }
339}
340
341#[cfg(feature = "extra-traits")]
342impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
343    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
344        let mut list = f.debug_list();
345        for (t, p) in &self.inner {
346            list.entry(t);
347            list.entry(p);
348        }
349        if let Some(last) = &self.last {
350            list.entry(last);
351        }
352        list.finish()
353    }
354}
355
356impl<T, P> FromIterator<T> for Punctuated<T, P>
357where
358    P: Default,
359{
360    fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
361        let mut ret = Punctuated::new();
362        ret.extend(i);
363        ret
364    }
365}
366
367impl<T, P> Extend<T> for Punctuated<T, P>
368where
369    P: Default,
370{
371    fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
372        for value in i {
373            self.push(value);
374        }
375    }
376}
377
378impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
379    fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
380        let mut ret = Punctuated::new();
381        ret.extend(i);
382        ret
383    }
384}
385
386impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
387    fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
388        assert!(self.empty_or_trailing());
389        let mut nomore = false;
390        for pair in i {
391            if nomore {
392                panic!("Punctuated extended with items after a Pair::End");
393            }
394            match pair {
395                Pair::Punctuated(a, b) => self.inner.push((a, b)),
396                Pair::End(a) => {
397                    self.last = Some(Box::new(a));
398                    nomore = true;
399                }
400            }
401        }
402    }
403}
404
405impl<T, P> IntoIterator for Punctuated<T, P> {
406    type Item = T;
407    type IntoIter = IntoIter<T>;
408
409    fn into_iter(self) -> Self::IntoIter {
410        let mut elements = Vec::with_capacity(self.len());
411        elements.extend(self.inner.into_iter().map(|pair| pair.0));
412        elements.extend(self.last.map(|t| *t));
413
414        IntoIter {
415            inner: elements.into_iter(),
416        }
417    }
418}
419
420impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
421    type Item = &'a T;
422    type IntoIter = Iter<'a, T>;
423
424    fn into_iter(self) -> Self::IntoIter {
425        Punctuated::iter(self)
426    }
427}
428
429impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
430    type Item = &'a mut T;
431    type IntoIter = IterMut<'a, T>;
432
433    fn into_iter(self) -> Self::IntoIter {
434        Punctuated::iter_mut(self)
435    }
436}
437
438impl<T, P> Default for Punctuated<T, P> {
439    fn default() -> Self {
440        Punctuated::new()
441    }
442}
443
444/// An iterator over borrowed pairs of type `Pair<&T, &P>`.
445///
446/// Refer to the [module documentation] for details about punctuated sequences.
447///
448/// [module documentation]: self
449pub struct Pairs<'a, T: 'a, P: 'a> {
450    inner: slice::Iter<'a, (T, P)>,
451    last: option::IntoIter<&'a T>,
452}
453
454impl<'a, T, P> Iterator for Pairs<'a, T, P> {
455    type Item = Pair<&'a T, &'a P>;
456
457    fn next(&mut self) -> Option<Self::Item> {
458        self.inner
459            .next()
460            .map(|(t, p)| Pair::Punctuated(t, p))
461            .or_else(|| self.last.next().map(Pair::End))
462    }
463
464    fn size_hint(&self) -> (usize, Option<usize>) {
465        (self.len(), Some(self.len()))
466    }
467}
468
469impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
470    fn next_back(&mut self) -> Option<Self::Item> {
471        self.last
472            .next()
473            .map(Pair::End)
474            .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
475    }
476}
477
478impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
479    fn len(&self) -> usize {
480        self.inner.len() + self.last.len()
481    }
482}
483
484// No Clone bound on T or P.
485impl<'a, T, P> Clone for Pairs<'a, T, P> {
486    fn clone(&self) -> Self {
487        Pairs {
488            inner: self.inner.clone(),
489            last: self.last.clone(),
490        }
491    }
492}
493
494/// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`.
495///
496/// Refer to the [module documentation] for details about punctuated sequences.
497///
498/// [module documentation]: self
499pub struct PairsMut<'a, T: 'a, P: 'a> {
500    inner: slice::IterMut<'a, (T, P)>,
501    last: option::IntoIter<&'a mut T>,
502}
503
504impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
505    type Item = Pair<&'a mut T, &'a mut P>;
506
507    fn next(&mut self) -> Option<Self::Item> {
508        self.inner
509            .next()
510            .map(|(t, p)| Pair::Punctuated(t, p))
511            .or_else(|| self.last.next().map(Pair::End))
512    }
513
514    fn size_hint(&self) -> (usize, Option<usize>) {
515        (self.len(), Some(self.len()))
516    }
517}
518
519impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
520    fn next_back(&mut self) -> Option<Self::Item> {
521        self.last
522            .next()
523            .map(Pair::End)
524            .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
525    }
526}
527
528impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
529    fn len(&self) -> usize {
530        self.inner.len() + self.last.len()
531    }
532}
533
534/// An iterator over owned pairs of type `Pair<T, P>`.
535///
536/// Refer to the [module documentation] for details about punctuated sequences.
537///
538/// [module documentation]: self
539#[derive(Clone)]
540pub struct IntoPairs<T, P> {
541    inner: vec::IntoIter<(T, P)>,
542    last: option::IntoIter<T>,
543}
544
545impl<T, P> Iterator for IntoPairs<T, P> {
546    type Item = Pair<T, P>;
547
548    fn next(&mut self) -> Option<Self::Item> {
549        self.inner
550            .next()
551            .map(|(t, p)| Pair::Punctuated(t, p))
552            .or_else(|| self.last.next().map(Pair::End))
553    }
554
555    fn size_hint(&self) -> (usize, Option<usize>) {
556        (self.len(), Some(self.len()))
557    }
558}
559
560impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
561    fn next_back(&mut self) -> Option<Self::Item> {
562        self.last
563            .next()
564            .map(Pair::End)
565            .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
566    }
567}
568
569impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
570    fn len(&self) -> usize {
571        self.inner.len() + self.last.len()
572    }
573}
574
575/// An iterator over owned values of type `T`.
576///
577/// Refer to the [module documentation] for details about punctuated sequences.
578///
579/// [module documentation]: self
580#[derive(Clone)]
581pub struct IntoIter<T> {
582    inner: vec::IntoIter<T>,
583}
584
585impl<T> Iterator for IntoIter<T> {
586    type Item = T;
587
588    fn next(&mut self) -> Option<Self::Item> {
589        self.inner.next()
590    }
591
592    fn size_hint(&self) -> (usize, Option<usize>) {
593        (self.len(), Some(self.len()))
594    }
595}
596
597impl<T> DoubleEndedIterator for IntoIter<T> {
598    fn next_back(&mut self) -> Option<Self::Item> {
599        self.inner.next_back()
600    }
601}
602
603impl<T> ExactSizeIterator for IntoIter<T> {
604    fn len(&self) -> usize {
605        self.inner.len()
606    }
607}
608
609/// An iterator over borrowed values of type `&T`.
610///
611/// Refer to the [module documentation] for details about punctuated sequences.
612///
613/// [module documentation]: self
614pub struct Iter<'a, T: 'a> {
615    // The `Item = &'a T` needs to be specified to support rustc 1.31 and older.
616    // On modern compilers we would be able to write just IterTrait<'a, T> where
617    // Item can be inferred unambiguously from the supertrait.
618    inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
619}
620
621trait IterTrait<'a, T: 'a>:
622    DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T>
623{
624    fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>;
625}
626
627struct PrivateIter<'a, T: 'a, P: 'a> {
628    inner: slice::Iter<'a, (T, P)>,
629    last: option::IntoIter<&'a T>,
630}
631
632#[cfg(any(feature = "full", feature = "derive"))]
633pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
634    Iter {
635        inner: Box::new(iter::empty()),
636    }
637}
638
639// No Clone bound on T.
640impl<'a, T> Clone for Iter<'a, T> {
641    fn clone(&self) -> Self {
642        Iter {
643            inner: self.inner.clone_box(),
644        }
645    }
646}
647
648impl<'a, T> Iterator for Iter<'a, T> {
649    type Item = &'a T;
650
651    fn next(&mut self) -> Option<Self::Item> {
652        self.inner.next()
653    }
654
655    fn size_hint(&self) -> (usize, Option<usize>) {
656        (self.len(), Some(self.len()))
657    }
658}
659
660impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
661    fn next_back(&mut self) -> Option<Self::Item> {
662        self.inner.next_back()
663    }
664}
665
666impl<'a, T> ExactSizeIterator for Iter<'a, T> {
667    fn len(&self) -> usize {
668        self.inner.len()
669    }
670}
671
672impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
673    type Item = &'a T;
674
675    fn next(&mut self) -> Option<Self::Item> {
676        self.inner
677            .next()
678            .map(|pair| &pair.0)
679            .or_else(|| self.last.next())
680    }
681}
682
683impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
684    fn next_back(&mut self) -> Option<Self::Item> {
685        self.last
686            .next()
687            .or_else(|| self.inner.next_back().map(|pair| &pair.0))
688    }
689}
690
691impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
692    fn len(&self) -> usize {
693        self.inner.len() + self.last.len()
694    }
695}
696
697// No Clone bound on T or P.
698impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
699    fn clone(&self) -> Self {
700        PrivateIter {
701            inner: self.inner.clone(),
702            last: self.last.clone(),
703        }
704    }
705}
706
707impl<'a, T: 'a, I: 'a> IterTrait<'a, T> for I
708where
709    I: DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T> + Clone,
710{
711    fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a> {
712        Box::new(self.clone())
713    }
714}
715
716/// An iterator over mutably borrowed values of type `&mut T`.
717///
718/// Refer to the [module documentation] for details about punctuated sequences.
719///
720/// [module documentation]: self
721pub struct IterMut<'a, T: 'a> {
722    inner: Box<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>,
723}
724
725trait IterMutTrait<'a, T: 'a>:
726    DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
727{
728}
729
730struct PrivateIterMut<'a, T: 'a, P: 'a> {
731    inner: slice::IterMut<'a, (T, P)>,
732    last: option::IntoIter<&'a mut T>,
733}
734
735#[cfg(any(feature = "full", feature = "derive"))]
736pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
737    IterMut {
738        inner: Box::new(iter::empty()),
739    }
740}
741
742impl<'a, T> Iterator for IterMut<'a, T> {
743    type Item = &'a mut T;
744
745    fn next(&mut self) -> Option<Self::Item> {
746        self.inner.next()
747    }
748
749    fn size_hint(&self) -> (usize, Option<usize>) {
750        (self.len(), Some(self.len()))
751    }
752}
753
754impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
755    fn next_back(&mut self) -> Option<Self::Item> {
756        self.inner.next_back()
757    }
758}
759
760impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
761    fn len(&self) -> usize {
762        self.inner.len()
763    }
764}
765
766impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
767    type Item = &'a mut T;
768
769    fn next(&mut self) -> Option<Self::Item> {
770        self.inner
771            .next()
772            .map(|pair| &mut pair.0)
773            .or_else(|| self.last.next())
774    }
775}
776
777impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
778    fn next_back(&mut self) -> Option<Self::Item> {
779        self.last
780            .next()
781            .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
782    }
783}
784
785impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
786    fn len(&self) -> usize {
787        self.inner.len() + self.last.len()
788    }
789}
790
791impl<'a, T: 'a, I: 'a> IterMutTrait<'a, T> for I where
792    I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
793{
794}
795
796/// A single syntax tree node of type `T` followed by its trailing punctuation
797/// of type `P` if any.
798///
799/// Refer to the [module documentation] for details about punctuated sequences.
800///
801/// [module documentation]: self
802#[cfg_attr(feature = "clone-impls", derive(Clone))]
803pub enum Pair<T, P> {
804    Punctuated(T, P),
805    End(T),
806}
807
808impl<T, P> Pair<T, P> {
809    /// Extracts the syntax tree node from this punctuated pair, discarding the
810    /// following punctuation.
811    pub fn into_value(self) -> T {
812        match self {
813            Pair::Punctuated(t, _) | Pair::End(t) => t,
814        }
815    }
816
817    /// Borrows the syntax tree node from this punctuated pair.
818    pub fn value(&self) -> &T {
819        match self {
820            Pair::Punctuated(t, _) | Pair::End(t) => t,
821        }
822    }
823
824    /// Mutably borrows the syntax tree node from this punctuated pair.
825    pub fn value_mut(&mut self) -> &mut T {
826        match self {
827            Pair::Punctuated(t, _) | Pair::End(t) => t,
828        }
829    }
830
831    /// Borrows the punctuation from this punctuated pair, unless this pair is
832    /// the final one and there is no trailing punctuation.
833    pub fn punct(&self) -> Option<&P> {
834        match self {
835            Pair::Punctuated(_, d) => Some(d),
836            Pair::End(_) => None,
837        }
838    }
839
840    /// Creates a punctuated pair out of a syntax tree node and an optional
841    /// following punctuation.
842    pub fn new(t: T, d: Option<P>) -> Self {
843        match d {
844            Some(d) => Pair::Punctuated(t, d),
845            None => Pair::End(t),
846        }
847    }
848
849    /// Produces this punctuated pair as a tuple of syntax tree node and
850    /// optional following punctuation.
851    pub fn into_tuple(self) -> (T, Option<P>) {
852        match self {
853            Pair::Punctuated(t, d) => (t, Some(d)),
854            Pair::End(t) => (t, None),
855        }
856    }
857}
858
859impl<T, P> Index<usize> for Punctuated<T, P> {
860    type Output = T;
861
862    fn index(&self, index: usize) -> &Self::Output {
863        if index == self.len() - 1 {
864            match &self.last {
865                Some(t) => t,
866                None => &self.inner[index].0,
867            }
868        } else {
869            &self.inner[index].0
870        }
871    }
872}
873
874impl<T, P> IndexMut<usize> for Punctuated<T, P> {
875    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
876        if index == self.len() - 1 {
877            match &mut self.last {
878                Some(t) => t,
879                None => &mut self.inner[index].0,
880            }
881        } else {
882            &mut self.inner[index].0
883        }
884    }
885}
886
887#[cfg(feature = "printing")]
888mod printing {
889    use super::*;
890    use proc_macro2::TokenStream;
891    use quote::{ToTokens, TokenStreamExt};
892
893    impl<T, P> ToTokens for Punctuated<T, P>
894    where
895        T: ToTokens,
896        P: ToTokens,
897    {
898        fn to_tokens(&self, tokens: &mut TokenStream) {
899            tokens.append_all(self.pairs())
900        }
901    }
902
903    impl<T, P> ToTokens for Pair<T, P>
904    where
905        T: ToTokens,
906        P: ToTokens,
907    {
908        fn to_tokens(&self, tokens: &mut TokenStream) {
909            match self {
910                Pair::Punctuated(a, b) => {
911                    a.to_tokens(tokens);
912                    b.to_tokens(tokens);
913                }
914                Pair::End(a) => a.to_tokens(tokens),
915            }
916        }
917    }
918}