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