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
23use crate::drops::{NoDrop, TrivialDrop};
24#[cfg(feature = "parsing")]
25use crate::error::Result;
26#[cfg(feature = "parsing")]
27use crate::parse::{Parse, ParseStream};
28#[cfg(feature = "parsing")]
29use crate::token::Token;
30#[cfg(feature = "extra-traits")]
31use std::fmt::{self, Debug};
32#[cfg(feature = "extra-traits")]
33use std::hash::{Hash, Hasher};
34#[cfg(any(feature = "full", feature = "derive"))]
35use std::iter;
36use std::ops::{Index, IndexMut};
37use std::option;
38use std::slice;
39use 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
47pub struct Punctuated<T, P> {
48 inner: Vec<(T, P)>,
49 last: Option<Box<T>>,
50}
51
52impl<T, P> Punctuated<T, P> {
53 /// Creates an empty punctuated sequence.
54 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.
63 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`.
71 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.
76 pub fn first(&self) -> Option<&T> {
77 self.iter().next()
78 }
79
80 /// Mutably borrows the first element in this sequence.
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.
86 pub fn last(&self) -> Option<&T> {
87 self.iter().next_back()
88 }
89
90 /// Mutably borrows the last element in this sequence.
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`.
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`.
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.
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.
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.
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.
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.
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.
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.
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.
205 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()`.
213 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`.
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.
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.
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")))]
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")))]
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")))]
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")))]
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")))]
362impl<T, P> Clone for Punctuated<T, P>
363where
364 T: Clone,
365 P: Clone,
366{
367 fn clone(&self) -> Self {
368 Punctuated {
369 inner: self.inner.clone(),
370 last: self.last.clone(),
371 }
372 }
373
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")))]
382impl<T, P> Eq for Punctuated<T, P>
383where
384 T: Eq,
385 P: Eq,
386{
387}
388
389#[cfg(feature = "extra-traits")]
390#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
391impl<T, P> PartialEq for Punctuated<T, P>
392where
393 T: PartialEq,
394 P: PartialEq,
395{
396 fn eq(&self, other: &Self) -> bool {
397 let Punctuated { inner: &Vec<(T, P)>, last: &Option> } = 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")))]
404impl<T, P> Hash for Punctuated<T, P>
405where
406 T: Hash,
407 P: Hash,
408{
409 fn hash<H: Hasher>(&self, state: &mut H) {
410 let Punctuated { inner: &Vec<(T, P)>, last: &Option> } = 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")))]
418impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
419 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
420 let mut list: DebugList<'_, '_> = f.debug_list();
421 for (t: &T, p: &P) in &self.inner {
422 list.entry(t);
423 list.entry(p);
424 }
425 if let Some(last: &Box) = &self.last {
426 list.entry(last);
427 }
428 list.finish()
429 }
430}
431
432impl<T, P> FromIterator<T> for Punctuated<T, P>
433where
434 P: Default,
435{
436 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
437 let mut ret: Punctuated = Punctuated::new();
438 ret.extend(iter:i);
439 ret
440 }
441}
442
443impl<T, P> Extend<T> for Punctuated<T, P>
444where
445 P: Default,
446{
447 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
448 for value: T in i {
449 self.push(value);
450 }
451 }
452}
453
454impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
455 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
456 let mut ret: Punctuated = Punctuated::new();
457 do_extend(&mut ret, i:i.into_iter());
458 ret
459 }
460}
461
462impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P>
463where
464 P: Default,
465{
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:i.into_iter());
471 }
472}
473
474fn do_extend<T, P, I>(punctuated: &mut Punctuated<T, P>, i: I)
475where
476 I: Iterator<Item = Pair<T, P>>,
477{
478 let mut nomore: bool = false;
479 for pair: Pair in i {
480 if nomore {
481 panic!("Punctuated extended with items after a Pair::End");
482 }
483 match pair {
484 Pair::Punctuated(a: T, b: P) => punctuated.inner.push((a, b)),
485 Pair::End(a: T) => {
486 punctuated.last = Some(Box::new(a));
487 nomore = true;
488 }
489 }
490 }
491}
492
493impl<T, P> IntoIterator for Punctuated<T, P> {
494 type Item = T;
495 type IntoIter = IntoIter<T>;
496
497 fn into_iter(self) -> Self::IntoIter {
498 let mut elements: Vec = Vec::with_capacity(self.len());
499 elements.extend(self.inner.into_iter().map(|pair: (T, P)| pair.0));
500 elements.extend(self.last.map(|t: Box| *t));
501
502 IntoIter {
503 inner: elements.into_iter(),
504 }
505 }
506}
507
508impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
509 type Item = &'a T;
510 type IntoIter = Iter<'a, T>;
511
512 fn into_iter(self) -> Self::IntoIter {
513 Punctuated::iter(self)
514 }
515}
516
517impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
518 type Item = &'a mut T;
519 type IntoIter = IterMut<'a, T>;
520
521 fn into_iter(self) -> Self::IntoIter {
522 Punctuated::iter_mut(self)
523 }
524}
525
526impl<T, P> Default for Punctuated<T, P> {
527 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
537pub struct Pairs<'a, T: 'a, P: 'a> {
538 inner: slice::Iter<'a, (T, P)>,
539 last: option::IntoIter<&'a T>,
540}
541
542impl<'a, T, P> Iterator for Pairs<'a, T, P> {
543 type Item = Pair<&'a T, &'a P>;
544
545 fn next(&mut self) -> Option<Self::Item> {
546 self.inner
547 .next()
548 .map(|(t: &T, p: &P)| Pair::Punctuated(t, p))
549 .or_else(|| self.last.next().map(Pair::End))
550 }
551
552 fn size_hint(&self) -> (usize, Option<usize>) {
553 (self.len(), Some(self.len()))
554 }
555}
556
557impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
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: &T, p: &P)| Pair::Punctuated(t, p)))
563 }
564}
565
566impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
567 fn len(&self) -> usize {
568 self.inner.len() + self.last.len()
569 }
570}
571
572// No Clone bound on T or P.
573impl<'a, T, P> Clone for Pairs<'a, T, P> {
574 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
587pub struct PairsMut<'a, T: 'a, P: 'a> {
588 inner: slice::IterMut<'a, (T, P)>,
589 last: option::IntoIter<&'a mut T>,
590}
591
592impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
593 type Item = Pair<&'a mut T, &'a mut P>;
594
595 fn next(&mut self) -> Option<Self::Item> {
596 self.inner
597 .next()
598 .map(|(t: &mut T, p: &mut P)| Pair::Punctuated(t, p))
599 .or_else(|| self.last.next().map(Pair::End))
600 }
601
602 fn size_hint(&self) -> (usize, Option<usize>) {
603 (self.len(), Some(self.len()))
604 }
605}
606
607impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
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: &mut T, p: &mut P)| Pair::Punctuated(t, p)))
613 }
614}
615
616impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
617 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
627pub struct IntoPairs<T, P> {
628 inner: vec::IntoIter<(T, P)>,
629 last: option::IntoIter<T>,
630}
631
632impl<T, P> Iterator for IntoPairs<T, P> {
633 type Item = Pair<T, P>;
634
635 fn next(&mut self) -> Option<Self::Item> {
636 self.inner
637 .next()
638 .map(|(t: T, p: P)| Pair::Punctuated(t, p))
639 .or_else(|| self.last.next().map(Pair::End))
640 }
641
642 fn size_hint(&self) -> (usize, Option<usize>) {
643 (self.len(), Some(self.len()))
644 }
645}
646
647impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
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: T, p: P)| Pair::Punctuated(t, p)))
653 }
654}
655
656impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
657 fn len(&self) -> usize {
658 self.inner.len() + self.last.len()
659 }
660}
661
662impl<T, P> Clone for IntoPairs<T, P>
663where
664 T: Clone,
665 P: Clone,
666{
667 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
680pub struct IntoIter<T> {
681 inner: vec::IntoIter<T>,
682}
683
684impl<T> Iterator for IntoIter<T> {
685 type Item = T;
686
687 fn next(&mut self) -> Option<Self::Item> {
688 self.inner.next()
689 }
690
691 fn size_hint(&self) -> (usize, Option<usize>) {
692 (self.len(), Some(self.len()))
693 }
694}
695
696impl<T> DoubleEndedIterator for IntoIter<T> {
697 fn next_back(&mut self) -> Option<Self::Item> {
698 self.inner.next_back()
699 }
700}
701
702impl<T> ExactSizeIterator for IntoIter<T> {
703 fn len(&self) -> usize {
704 self.inner.len()
705 }
706}
707
708impl<T> Clone for IntoIter<T>
709where
710 T: Clone,
711{
712 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
724pub struct Iter<'a, T: 'a> {
725 inner: Box<NoDrop<dyn IterTrait<'a, T> + 'a>>,
726}
727
728trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> + DoubleEndedIterator + ExactSizeIterator {
729 fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>>;
730}
731
732struct PrivateIter<'a, T: 'a, P: 'a> {
733 inner: slice::Iter<'a, (T, P)>,
734 last: option::IntoIter<&'a T>,
735}
736
737impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
738where
739 slice::Iter<'a, (T, P)>: TrivialDrop,
740 option::IntoIter<&'a T>: TrivialDrop,
741{
742}
743
744#[cfg(any(feature = "full", feature = "derive"))]
745pub(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.
752impl<'a, T> Clone for Iter<'a, T> {
753 fn clone(&self) -> Self {
754 Iter {
755 inner: self.inner.clone_box(),
756 }
757 }
758}
759
760impl<'a, T> Iterator for Iter<'a, T> {
761 type Item = &'a T;
762
763 fn next(&mut self) -> Option<Self::Item> {
764 self.inner.next()
765 }
766
767 fn size_hint(&self) -> (usize, Option<usize>) {
768 (self.len(), Some(self.len()))
769 }
770}
771
772impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
773 fn next_back(&mut self) -> Option<Self::Item> {
774 self.inner.next_back()
775 }
776}
777
778impl<'a, T> ExactSizeIterator for Iter<'a, T> {
779 fn len(&self) -> usize {
780 self.inner.len()
781 }
782}
783
784impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
785 type Item = &'a T;
786
787 fn next(&mut self) -> Option<Self::Item> {
788 self.inner
789 .next()
790 .map(|pair: &(T, P)| &pair.0)
791 .or_else(|| self.last.next())
792 }
793}
794
795impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
796 fn next_back(&mut self) -> Option<Self::Item> {
797 self.last
798 .next()
799 .or_else(|| self.inner.next_back().map(|pair: &(T, P)| &pair.0))
800 }
801}
802
803impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
804 fn len(&self) -> usize {
805 self.inner.len() + self.last.len()
806 }
807}
808
809// No Clone bound on T or P.
810impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
811 fn clone(&self) -> Self {
812 PrivateIter {
813 inner: self.inner.clone(),
814 last: self.last.clone(),
815 }
816 }
817}
818
819impl<'a, T, I> IterTrait<'a, T> for I
820where
821 T: 'a,
822 I: DoubleEndedIterator<Item = &'a T>
823 + ExactSizeIterator<Item = &'a T>
824 + Clone
825 + TrivialDrop
826 + 'a,
827{
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
838pub struct IterMut<'a, T: 'a> {
839 inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
840}
841
842trait IterMutTrait<'a, T: 'a>:
843 DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
844{
845}
846
847struct PrivateIterMut<'a, T: 'a, P: 'a> {
848 inner: slice::IterMut<'a, (T, P)>,
849 last: option::IntoIter<&'a mut T>,
850}
851
852impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
853where
854 slice::IterMut<'a, (T, P)>: TrivialDrop,
855 option::IntoIter<&'a mut T>: TrivialDrop,
856{
857}
858
859#[cfg(any(feature = "full", feature = "derive"))]
860pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
861 IterMut {
862 inner: Box::new(NoDrop::new(iter::empty())),
863 }
864}
865
866impl<'a, T> Iterator for IterMut<'a, T> {
867 type Item = &'a mut T;
868
869 fn next(&mut self) -> Option<Self::Item> {
870 self.inner.next()
871 }
872
873 fn size_hint(&self) -> (usize, Option<usize>) {
874 (self.len(), Some(self.len()))
875 }
876}
877
878impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
879 fn next_back(&mut self) -> Option<Self::Item> {
880 self.inner.next_back()
881 }
882}
883
884impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
885 fn len(&self) -> usize {
886 self.inner.len()
887 }
888}
889
890impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
891 type Item = &'a mut T;
892
893 fn next(&mut self) -> Option<Self::Item> {
894 self.inner
895 .next()
896 .map(|pair: &mut (T, P)| &mut pair.0)
897 .or_else(|| self.last.next())
898 }
899}
900
901impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
902 fn next_back(&mut self) -> Option<Self::Item> {
903 self.last
904 .next()
905 .or_else(|| self.inner.next_back().map(|pair: &mut (T, P)| &mut pair.0))
906 }
907}
908
909impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
910 fn len(&self) -> usize {
911 self.inner.len() + self.last.len()
912 }
913}
914
915impl<'a, T, I> IterMutTrait<'a, T> for I
916where
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
928pub enum Pair<T, P> {
929 Punctuated(T, P),
930 End(T),
931}
932
933impl<T, P> Pair<T, P> {
934 /// Extracts the syntax tree node from this punctuated pair, discarding the
935 /// following punctuation.
936 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.
943 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.
950 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.
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 /// ```
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.
992 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.
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")))]
1011impl<T, P> Pair<&T, &P> {
1012 pub fn cloned(self) -> Pair<T, P>
1013 where
1014 T: Clone,
1015 P: Clone,
1016 {
1017 match self {
1018 Pair::Punctuated(t: &T, p: &P) => Pair::Punctuated(t.clone(), p.clone()),
1019 Pair::End(t: &T) => Pair::End(t.clone()),
1020 }
1021 }
1022}
1023
1024#[cfg(feature = "clone-impls")]
1025#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
1026impl<T, P> Clone for Pair<T, P>
1027where
1028 T: Clone,
1029 P: Clone,
1030{
1031 fn clone(&self) -> Self {
1032 match self {
1033 Pair::Punctuated(t: &T, p: &P) => Pair::Punctuated(t.clone(), p.clone()),
1034 Pair::End(t: &T) => Pair::End(t.clone()),
1035 }
1036 }
1037}
1038
1039#[cfg(feature = "clone-impls")]
1040#[cfg_attr(doc_cfg, doc(cfg(feature = "clone-impls")))]
1041impl<T, P> Copy for Pair<T, P>
1042where
1043 T: Copy,
1044 P: Copy,
1045{
1046}
1047
1048impl<T, P> Index<usize> for Punctuated<T, P> {
1049 type Output = T;
1050
1051 fn index(&self, index: usize) -> &Self::Output {
1052 if index == self.len() - 1 {
1053 match &self.last {
1054 Some(t: &Box) => t,
1055 None => &self.inner[index].0,
1056 }
1057 } else {
1058 &self.inner[index].0
1059 }
1060 }
1061}
1062
1063impl<T, P> IndexMut<usize> for Punctuated<T, P> {
1064 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1065 if index == self.len() - 1 {
1066 match &mut self.last {
1067 Some(t: &mut Box) => 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")]
1077mod 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 {
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 {
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