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