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