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