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