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