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