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