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>`]: struct.Punctuated.html
17 //!
18 //! ```text
19 //! a_function_call(arg1, arg2, arg3);
20 //! ~~~~^ ~~~~^ ~~~~
21 //! ```
22
23 #[cfg(feature = "extra-traits")]
24 use std::fmt::{self, Debug};
25 #[cfg(any(feature = "full", feature = "derive"))]
26 use std::iter;
27 use std::iter::FromIterator;
28 use std::ops::{Index, IndexMut};
29 use std::option;
30 use std::slice;
31 use std::vec;
32
33 #[cfg(feature = "parsing")]
34 use crate::parse::{Parse, ParseStream, Result};
35 #[cfg(feature = "parsing")]
36 use crate::token::Token;
37
38 /// A punctuated sequence of syntax tree nodes of type `T` separated by
39 /// punctuation of type `P`.
40 ///
41 /// Refer to the [module documentation] for details about punctuated sequences.
42 ///
43 /// [module documentation]: self
44 #[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))]
45 #[cfg_attr(feature = "clone-impls", derive(Clone))]
46 pub struct Punctuated<T, P> {
47 inner: Vec<(T, P)>,
48 last: Option<Box<T>>,
49 }
50
51 impl<T, P> Punctuated<T, P> {
52 /// Creates an empty punctuated sequence.
new() -> Punctuated<T, P>53 pub fn new() -> Punctuated<T, P> {
54 Punctuated {
55 inner: Vec::new(),
56 last: None,
57 }
58 }
59
60 /// Determines whether this punctuated sequence is empty, meaning it
61 /// contains no syntax tree nodes or punctuation.
is_empty(&self) -> bool62 pub fn is_empty(&self) -> bool {
63 self.inner.len() == 0 && self.last.is_none()
64 }
65
66 /// Returns the number of syntax tree nodes in this punctuated sequence.
67 ///
68 /// This is the number of nodes of type `T`, not counting the punctuation of
69 /// type `P`.
len(&self) -> usize70 pub fn len(&self) -> usize {
71 self.inner.len() + if self.last.is_some() { 1 } else { 0 }
72 }
73
74 /// Borrows the first element in this sequence.
first(&self) -> Option<&T>75 pub fn first(&self) -> Option<&T> {
76 self.iter().next()
77 }
78
79 /// Borrows the last element in this sequence.
last(&self) -> Option<&T>80 pub fn last(&self) -> Option<&T> {
81 if self.last.is_some() {
82 self.last.as_ref().map(Box::as_ref)
83 } else {
84 self.inner.last().map(|pair| &pair.0)
85 }
86 }
87
88 /// Mutably borrows the last element in this sequence.
last_mut(&mut self) -> Option<&mut T>89 pub fn last_mut(&mut self) -> Option<&mut T> {
90 if self.last.is_some() {
91 self.last.as_mut().map(Box::as_mut)
92 } else {
93 self.inner.last_mut().map(|pair| &mut pair.0)
94 }
95 }
96
97 /// Returns an iterator over borrowed syntax tree nodes of type `&T`.
iter(&self) -> Iter<T>98 pub fn iter(&self) -> Iter<T> {
99 Iter {
100 inner: Box::new(PrivateIter {
101 inner: self.inner.iter(),
102 last: self.last.as_ref().map(Box::as_ref).into_iter(),
103 }),
104 }
105 }
106
107 /// Returns an iterator over mutably borrowed syntax tree nodes of type
108 /// `&mut T`.
iter_mut(&mut self) -> IterMut<T>109 pub fn iter_mut(&mut self) -> IterMut<T> {
110 IterMut {
111 inner: Box::new(PrivateIterMut {
112 inner: self.inner.iter_mut(),
113 last: self.last.as_mut().map(Box::as_mut).into_iter(),
114 }),
115 }
116 }
117
118 /// Returns an iterator over the contents of this sequence as borrowed
119 /// punctuated pairs.
pairs(&self) -> Pairs<T, P>120 pub fn pairs(&self) -> Pairs<T, P> {
121 Pairs {
122 inner: self.inner.iter(),
123 last: self.last.as_ref().map(Box::as_ref).into_iter(),
124 }
125 }
126
127 /// Returns an iterator over the contents of this sequence as mutably
128 /// borrowed punctuated pairs.
pairs_mut(&mut self) -> PairsMut<T, P>129 pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
130 PairsMut {
131 inner: self.inner.iter_mut(),
132 last: self.last.as_mut().map(Box::as_mut).into_iter(),
133 }
134 }
135
136 /// Returns an iterator over the contents of this sequence as owned
137 /// punctuated pairs.
into_pairs(self) -> IntoPairs<T, P>138 pub fn into_pairs(self) -> IntoPairs<T, P> {
139 IntoPairs {
140 inner: self.inner.into_iter(),
141 last: self.last.map(|t| *t).into_iter(),
142 }
143 }
144
145 /// Appends a syntax tree node onto the end of this punctuated sequence. The
146 /// sequence must previously have a trailing punctuation.
147 ///
148 /// Use [`push`] instead if the punctuated sequence may or may not already
149 /// have trailing punctuation.
150 ///
151 /// [`push`]: Punctuated::push
152 ///
153 /// # Panics
154 ///
155 /// Panics if the sequence does not already have a trailing punctuation when
156 /// this method is called.
push_value(&mut self, value: T)157 pub fn push_value(&mut self, value: T) {
158 assert!(self.empty_or_trailing());
159 self.last = Some(Box::new(value));
160 }
161
162 /// Appends a trailing punctuation onto the end of this punctuated sequence.
163 /// The sequence must be non-empty and must not already have trailing
164 /// punctuation.
165 ///
166 /// # Panics
167 ///
168 /// Panics if the sequence is empty or already has a trailing punctuation.
push_punct(&mut self, punctuation: P)169 pub fn push_punct(&mut self, punctuation: P) {
170 assert!(self.last.is_some());
171 let last = self.last.take().unwrap();
172 self.inner.push((*last, punctuation));
173 }
174
175 /// Removes the last punctuated pair from this sequence, or `None` if the
176 /// sequence is empty.
pop(&mut self) -> Option<Pair<T, P>>177 pub fn pop(&mut self) -> Option<Pair<T, P>> {
178 if self.last.is_some() {
179 self.last.take().map(|t| Pair::End(*t))
180 } else {
181 self.inner.pop().map(|(t, d)| Pair::Punctuated(t, d))
182 }
183 }
184
185 /// Determines whether this punctuated sequence ends with a trailing
186 /// punctuation.
trailing_punct(&self) -> bool187 pub fn trailing_punct(&self) -> bool {
188 self.last.is_none() && !self.is_empty()
189 }
190
191 /// Returns true if either this `Punctuated` is empty, or it has a trailing
192 /// punctuation.
193 ///
194 /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
empty_or_trailing(&self) -> bool195 pub fn empty_or_trailing(&self) -> bool {
196 self.last.is_none()
197 }
198
199 /// Appends a syntax tree node onto the end of this punctuated sequence.
200 ///
201 /// If there is not a trailing punctuation in this sequence when this method
202 /// is called, the default value of punctuation type `P` is inserted before
203 /// the given value of type `T`.
push(&mut self, value: T) where P: Default,204 pub fn push(&mut self, value: T)
205 where
206 P: Default,
207 {
208 if !self.empty_or_trailing() {
209 self.push_punct(Default::default());
210 }
211 self.push_value(value);
212 }
213
214 /// Inserts an element at position `index`.
215 ///
216 /// # Panics
217 ///
218 /// Panics if `index` is greater than the number of elements previously in
219 /// this punctuated sequence.
insert(&mut self, index: usize, value: T) where P: Default,220 pub fn insert(&mut self, index: usize, value: T)
221 where
222 P: Default,
223 {
224 assert!(index <= self.len());
225
226 if index == self.len() {
227 self.push(value);
228 } else {
229 self.inner.insert(index, (value, Default::default()));
230 }
231 }
232
233 /// Parses zero or more occurrences of `T` separated by punctuation of type
234 /// `P`, with optional trailing punctuation.
235 ///
236 /// Parsing continues until the end of this parse stream. The entire content
237 /// of this parse stream must consist of `T` and `P`.
238 ///
239 /// *This function is available if Syn is built with the `"parsing"`
240 /// feature.*
241 #[cfg(feature = "parsing")]
parse_terminated(input: ParseStream) -> Result<Self> where T: Parse, P: Parse,242 pub fn parse_terminated(input: ParseStream) -> Result<Self>
243 where
244 T: Parse,
245 P: Parse,
246 {
247 Self::parse_terminated_with(input, T::parse)
248 }
249
250 /// Parses zero or more occurrences of `T` using the given parse function,
251 /// separated by punctuation of type `P`, with optional trailing
252 /// punctuation.
253 ///
254 /// Like [`parse_terminated`], the entire content of this stream is expected
255 /// to be parsed.
256 ///
257 /// [`parse_terminated`]: Punctuated::parse_terminated
258 ///
259 /// *This function is available if Syn is built with the `"parsing"`
260 /// feature.*
261 #[cfg(feature = "parsing")]
parse_terminated_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Parse,262 pub fn parse_terminated_with(
263 input: ParseStream,
264 parser: fn(ParseStream) -> Result<T>,
265 ) -> Result<Self>
266 where
267 P: Parse,
268 {
269 let mut punctuated = Punctuated::new();
270
271 loop {
272 if input.is_empty() {
273 break;
274 }
275 let value = parser(input)?;
276 punctuated.push_value(value);
277 if input.is_empty() {
278 break;
279 }
280 let punct = input.parse()?;
281 punctuated.push_punct(punct);
282 }
283
284 Ok(punctuated)
285 }
286
287 /// Parses one or more occurrences of `T` separated by punctuation of type
288 /// `P`, not accepting trailing punctuation.
289 ///
290 /// Parsing continues as long as punctuation `P` is present at the head of
291 /// the stream. This method returns upon parsing a `T` and observing that it
292 /// is not followed by a `P`, even if there are remaining tokens in the
293 /// stream.
294 ///
295 /// *This function is available if Syn is built with the `"parsing"`
296 /// feature.*
297 #[cfg(feature = "parsing")]
parse_separated_nonempty(input: ParseStream) -> Result<Self> where T: Parse, P: Token + Parse,298 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
299 where
300 T: Parse,
301 P: Token + Parse,
302 {
303 Self::parse_separated_nonempty_with(input, T::parse)
304 }
305
306 /// Parses one or more occurrences of `T` using the given parse function,
307 /// separated by punctuation of type `P`, not accepting trailing
308 /// punctuation.
309 ///
310 /// Like [`parse_separated_nonempty`], may complete early without parsing
311 /// the entire content of this stream.
312 ///
313 /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
314 ///
315 /// *This function is available if Syn is built with the `"parsing"`
316 /// feature.*
317 #[cfg(feature = "parsing")]
parse_separated_nonempty_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Token + Parse,318 pub fn parse_separated_nonempty_with(
319 input: ParseStream,
320 parser: fn(ParseStream) -> Result<T>,
321 ) -> Result<Self>
322 where
323 P: Token + Parse,
324 {
325 let mut punctuated = Punctuated::new();
326
327 loop {
328 let value = parser(input)?;
329 punctuated.push_value(value);
330 if !P::peek(input.cursor()) {
331 break;
332 }
333 let punct = input.parse()?;
334 punctuated.push_punct(punct);
335 }
336
337 Ok(punctuated)
338 }
339 }
340
341 #[cfg(feature = "extra-traits")]
342 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result343 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
344 let mut list = f.debug_list();
345 for (t, p) in &self.inner {
346 list.entry(t);
347 list.entry(p);
348 }
349 if let Some(last) = &self.last {
350 list.entry(last);
351 }
352 list.finish()
353 }
354 }
355
356 impl<T, P> FromIterator<T> for Punctuated<T, P>
357 where
358 P: Default,
359 {
from_iter<I: IntoIterator<Item = T>>(i: I) -> Self360 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
361 let mut ret = Punctuated::new();
362 ret.extend(i);
363 ret
364 }
365 }
366
367 impl<T, P> Extend<T> for Punctuated<T, P>
368 where
369 P: Default,
370 {
extend<I: IntoIterator<Item = T>>(&mut self, i: I)371 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
372 for value in i {
373 self.push(value);
374 }
375 }
376 }
377
378 impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self379 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
380 let mut ret = Punctuated::new();
381 ret.extend(i);
382 ret
383 }
384 }
385
386 impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I)387 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
388 assert!(self.empty_or_trailing());
389 let mut nomore = false;
390 for pair in i {
391 if nomore {
392 panic!("Punctuated extended with items after a Pair::End");
393 }
394 match pair {
395 Pair::Punctuated(a, b) => self.inner.push((a, b)),
396 Pair::End(a) => {
397 self.last = Some(Box::new(a));
398 nomore = true;
399 }
400 }
401 }
402 }
403 }
404
405 impl<T, P> IntoIterator for Punctuated<T, P> {
406 type Item = T;
407 type IntoIter = IntoIter<T>;
408
into_iter(self) -> Self::IntoIter409 fn into_iter(self) -> Self::IntoIter {
410 let mut elements = Vec::with_capacity(self.len());
411 elements.extend(self.inner.into_iter().map(|pair| pair.0));
412 elements.extend(self.last.map(|t| *t));
413
414 IntoIter {
415 inner: elements.into_iter(),
416 }
417 }
418 }
419
420 impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
421 type Item = &'a T;
422 type IntoIter = Iter<'a, T>;
423
into_iter(self) -> Self::IntoIter424 fn into_iter(self) -> Self::IntoIter {
425 Punctuated::iter(self)
426 }
427 }
428
429 impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
430 type Item = &'a mut T;
431 type IntoIter = IterMut<'a, T>;
432
into_iter(self) -> Self::IntoIter433 fn into_iter(self) -> Self::IntoIter {
434 Punctuated::iter_mut(self)
435 }
436 }
437
438 impl<T, P> Default for Punctuated<T, P> {
default() -> Self439 fn default() -> Self {
440 Punctuated::new()
441 }
442 }
443
444 /// An iterator over borrowed pairs of type `Pair<&T, &P>`.
445 ///
446 /// Refer to the [module documentation] for details about punctuated sequences.
447 ///
448 /// [module documentation]: self
449 pub struct Pairs<'a, T: 'a, P: 'a> {
450 inner: slice::Iter<'a, (T, P)>,
451 last: option::IntoIter<&'a T>,
452 }
453
454 impl<'a, T, P> Iterator for Pairs<'a, T, P> {
455 type Item = Pair<&'a T, &'a P>;
456
next(&mut self) -> Option<Self::Item>457 fn next(&mut self) -> Option<Self::Item> {
458 self.inner
459 .next()
460 .map(|(t, p)| Pair::Punctuated(t, p))
461 .or_else(|| self.last.next().map(Pair::End))
462 }
463
size_hint(&self) -> (usize, Option<usize>)464 fn size_hint(&self) -> (usize, Option<usize>) {
465 (self.len(), Some(self.len()))
466 }
467 }
468
469 impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>470 fn next_back(&mut self) -> Option<Self::Item> {
471 self.last
472 .next()
473 .map(Pair::End)
474 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
475 }
476 }
477
478 impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
len(&self) -> usize479 fn len(&self) -> usize {
480 self.inner.len() + self.last.len()
481 }
482 }
483
484 // No Clone bound on T or P.
485 impl<'a, T, P> Clone for Pairs<'a, T, P> {
clone(&self) -> Self486 fn clone(&self) -> Self {
487 Pairs {
488 inner: self.inner.clone(),
489 last: self.last.clone(),
490 }
491 }
492 }
493
494 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`.
495 ///
496 /// Refer to the [module documentation] for details about punctuated sequences.
497 ///
498 /// [module documentation]: self
499 pub struct PairsMut<'a, T: 'a, P: 'a> {
500 inner: slice::IterMut<'a, (T, P)>,
501 last: option::IntoIter<&'a mut T>,
502 }
503
504 impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
505 type Item = Pair<&'a mut T, &'a mut P>;
506
next(&mut self) -> Option<Self::Item>507 fn next(&mut self) -> Option<Self::Item> {
508 self.inner
509 .next()
510 .map(|(t, p)| Pair::Punctuated(t, p))
511 .or_else(|| self.last.next().map(Pair::End))
512 }
513
size_hint(&self) -> (usize, Option<usize>)514 fn size_hint(&self) -> (usize, Option<usize>) {
515 (self.len(), Some(self.len()))
516 }
517 }
518
519 impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>520 fn next_back(&mut self) -> Option<Self::Item> {
521 self.last
522 .next()
523 .map(Pair::End)
524 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
525 }
526 }
527
528 impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
len(&self) -> usize529 fn len(&self) -> usize {
530 self.inner.len() + self.last.len()
531 }
532 }
533
534 /// An iterator over owned pairs of type `Pair<T, P>`.
535 ///
536 /// Refer to the [module documentation] for details about punctuated sequences.
537 ///
538 /// [module documentation]: self
539 #[derive(Clone)]
540 pub struct IntoPairs<T, P> {
541 inner: vec::IntoIter<(T, P)>,
542 last: option::IntoIter<T>,
543 }
544
545 impl<T, P> Iterator for IntoPairs<T, P> {
546 type Item = Pair<T, P>;
547
next(&mut self) -> Option<Self::Item>548 fn next(&mut self) -> Option<Self::Item> {
549 self.inner
550 .next()
551 .map(|(t, p)| Pair::Punctuated(t, p))
552 .or_else(|| self.last.next().map(Pair::End))
553 }
554
size_hint(&self) -> (usize, Option<usize>)555 fn size_hint(&self) -> (usize, Option<usize>) {
556 (self.len(), Some(self.len()))
557 }
558 }
559
560 impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
next_back(&mut self) -> Option<Self::Item>561 fn next_back(&mut self) -> Option<Self::Item> {
562 self.last
563 .next()
564 .map(Pair::End)
565 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
566 }
567 }
568
569 impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
len(&self) -> usize570 fn len(&self) -> usize {
571 self.inner.len() + self.last.len()
572 }
573 }
574
575 /// An iterator over owned values of type `T`.
576 ///
577 /// Refer to the [module documentation] for details about punctuated sequences.
578 ///
579 /// [module documentation]: self
580 #[derive(Clone)]
581 pub struct IntoIter<T> {
582 inner: vec::IntoIter<T>,
583 }
584
585 impl<T> Iterator for IntoIter<T> {
586 type Item = T;
587
next(&mut self) -> Option<Self::Item>588 fn next(&mut self) -> Option<Self::Item> {
589 self.inner.next()
590 }
591
size_hint(&self) -> (usize, Option<usize>)592 fn size_hint(&self) -> (usize, Option<usize>) {
593 (self.len(), Some(self.len()))
594 }
595 }
596
597 impl<T> DoubleEndedIterator for IntoIter<T> {
next_back(&mut self) -> Option<Self::Item>598 fn next_back(&mut self) -> Option<Self::Item> {
599 self.inner.next_back()
600 }
601 }
602
603 impl<T> ExactSizeIterator for IntoIter<T> {
len(&self) -> usize604 fn len(&self) -> usize {
605 self.inner.len()
606 }
607 }
608
609 /// An iterator over borrowed values of type `&T`.
610 ///
611 /// Refer to the [module documentation] for details about punctuated sequences.
612 ///
613 /// [module documentation]: self
614 pub struct Iter<'a, T: 'a> {
615 // The `Item = &'a T` needs to be specified to support rustc 1.31 and older.
616 // On modern compilers we would be able to write just IterTrait<'a, T> where
617 // Item can be inferred unambiguously from the supertrait.
618 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
619 }
620
621 trait IterTrait<'a, T: 'a>:
622 DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T>
623 {
clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>624 fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>;
625 }
626
627 struct PrivateIter<'a, T: 'a, P: 'a> {
628 inner: slice::Iter<'a, (T, P)>,
629 last: option::IntoIter<&'a T>,
630 }
631
632 #[cfg(any(feature = "full", feature = "derive"))]
empty_punctuated_iter<'a, T>() -> Iter<'a, T>633 pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
634 Iter {
635 inner: Box::new(iter::empty()),
636 }
637 }
638
639 // No Clone bound on T.
640 impl<'a, T> Clone for Iter<'a, T> {
clone(&self) -> Self641 fn clone(&self) -> Self {
642 Iter {
643 inner: self.inner.clone_box(),
644 }
645 }
646 }
647
648 impl<'a, T> Iterator for Iter<'a, T> {
649 type Item = &'a T;
650
next(&mut self) -> Option<Self::Item>651 fn next(&mut self) -> Option<Self::Item> {
652 self.inner.next()
653 }
654
size_hint(&self) -> (usize, Option<usize>)655 fn size_hint(&self) -> (usize, Option<usize>) {
656 (self.len(), Some(self.len()))
657 }
658 }
659
660 impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
next_back(&mut self) -> Option<Self::Item>661 fn next_back(&mut self) -> Option<Self::Item> {
662 self.inner.next_back()
663 }
664 }
665
666 impl<'a, T> ExactSizeIterator for Iter<'a, T> {
len(&self) -> usize667 fn len(&self) -> usize {
668 self.inner.len()
669 }
670 }
671
672 impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
673 type Item = &'a T;
674
next(&mut self) -> Option<Self::Item>675 fn next(&mut self) -> Option<Self::Item> {
676 self.inner
677 .next()
678 .map(|pair| &pair.0)
679 .or_else(|| self.last.next())
680 }
681 }
682
683 impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>684 fn next_back(&mut self) -> Option<Self::Item> {
685 self.last
686 .next()
687 .or_else(|| self.inner.next_back().map(|pair| &pair.0))
688 }
689 }
690
691 impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
len(&self) -> usize692 fn len(&self) -> usize {
693 self.inner.len() + self.last.len()
694 }
695 }
696
697 // No Clone bound on T or P.
698 impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
clone(&self) -> Self699 fn clone(&self) -> Self {
700 PrivateIter {
701 inner: self.inner.clone(),
702 last: self.last.clone(),
703 }
704 }
705 }
706
707 impl<'a, T: 'a, I: 'a> IterTrait<'a, T> for I
708 where
709 I: DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T> + Clone,
710 {
clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>711 fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a> {
712 Box::new(self.clone())
713 }
714 }
715
716 /// An iterator over mutably borrowed values of type `&mut T`.
717 ///
718 /// Refer to the [module documentation] for details about punctuated sequences.
719 ///
720 /// [module documentation]: self
721 pub struct IterMut<'a, T: 'a> {
722 inner: Box<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>,
723 }
724
725 trait IterMutTrait<'a, T: 'a>:
726 DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
727 {
728 }
729
730 struct PrivateIterMut<'a, T: 'a, P: 'a> {
731 inner: slice::IterMut<'a, (T, P)>,
732 last: option::IntoIter<&'a mut T>,
733 }
734
735 #[cfg(any(feature = "full", feature = "derive"))]
empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T>736 pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
737 IterMut {
738 inner: Box::new(iter::empty()),
739 }
740 }
741
742 impl<'a, T> Iterator for IterMut<'a, T> {
743 type Item = &'a mut T;
744
next(&mut self) -> Option<Self::Item>745 fn next(&mut self) -> Option<Self::Item> {
746 self.inner.next()
747 }
748
size_hint(&self) -> (usize, Option<usize>)749 fn size_hint(&self) -> (usize, Option<usize>) {
750 (self.len(), Some(self.len()))
751 }
752 }
753
754 impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
next_back(&mut self) -> Option<Self::Item>755 fn next_back(&mut self) -> Option<Self::Item> {
756 self.inner.next_back()
757 }
758 }
759
760 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
len(&self) -> usize761 fn len(&self) -> usize {
762 self.inner.len()
763 }
764 }
765
766 impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
767 type Item = &'a mut T;
768
next(&mut self) -> Option<Self::Item>769 fn next(&mut self) -> Option<Self::Item> {
770 self.inner
771 .next()
772 .map(|pair| &mut pair.0)
773 .or_else(|| self.last.next())
774 }
775 }
776
777 impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>778 fn next_back(&mut self) -> Option<Self::Item> {
779 self.last
780 .next()
781 .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
782 }
783 }
784
785 impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
len(&self) -> usize786 fn len(&self) -> usize {
787 self.inner.len() + self.last.len()
788 }
789 }
790
791 impl<'a, T: 'a, I: 'a> IterMutTrait<'a, T> for I where
792 I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
793 {
794 }
795
796 /// A single syntax tree node of type `T` followed by its trailing punctuation
797 /// of type `P` if any.
798 ///
799 /// Refer to the [module documentation] for details about punctuated sequences.
800 ///
801 /// [module documentation]: self
802 #[cfg_attr(feature = "clone-impls", derive(Clone))]
803 pub enum Pair<T, P> {
804 Punctuated(T, P),
805 End(T),
806 }
807
808 impl<T, P> Pair<T, P> {
809 /// Extracts the syntax tree node from this punctuated pair, discarding the
810 /// following punctuation.
into_value(self) -> T811 pub fn into_value(self) -> T {
812 match self {
813 Pair::Punctuated(t, _) | Pair::End(t) => t,
814 }
815 }
816
817 /// Borrows the syntax tree node from this punctuated pair.
value(&self) -> &T818 pub fn value(&self) -> &T {
819 match self {
820 Pair::Punctuated(t, _) | Pair::End(t) => t,
821 }
822 }
823
824 /// Mutably borrows the syntax tree node from this punctuated pair.
value_mut(&mut self) -> &mut T825 pub fn value_mut(&mut self) -> &mut T {
826 match self {
827 Pair::Punctuated(t, _) | Pair::End(t) => t,
828 }
829 }
830
831 /// Borrows the punctuation from this punctuated pair, unless this pair is
832 /// the final one and there is no trailing punctuation.
punct(&self) -> Option<&P>833 pub fn punct(&self) -> Option<&P> {
834 match self {
835 Pair::Punctuated(_, d) => Some(d),
836 Pair::End(_) => None,
837 }
838 }
839
840 /// Creates a punctuated pair out of a syntax tree node and an optional
841 /// following punctuation.
new(t: T, d: Option<P>) -> Self842 pub fn new(t: T, d: Option<P>) -> Self {
843 match d {
844 Some(d) => Pair::Punctuated(t, d),
845 None => Pair::End(t),
846 }
847 }
848
849 /// Produces this punctuated pair as a tuple of syntax tree node and
850 /// optional following punctuation.
into_tuple(self) -> (T, Option<P>)851 pub fn into_tuple(self) -> (T, Option<P>) {
852 match self {
853 Pair::Punctuated(t, d) => (t, Some(d)),
854 Pair::End(t) => (t, None),
855 }
856 }
857 }
858
859 impl<T, P> Index<usize> for Punctuated<T, P> {
860 type Output = T;
861
index(&self, index: usize) -> &Self::Output862 fn index(&self, index: usize) -> &Self::Output {
863 if index == self.len() - 1 {
864 match &self.last {
865 Some(t) => t,
866 None => &self.inner[index].0,
867 }
868 } else {
869 &self.inner[index].0
870 }
871 }
872 }
873
874 impl<T, P> IndexMut<usize> for Punctuated<T, P> {
index_mut(&mut self, index: usize) -> &mut Self::Output875 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
876 if index == self.len() - 1 {
877 match &mut self.last {
878 Some(t) => t,
879 None => &mut self.inner[index].0,
880 }
881 } else {
882 &mut self.inner[index].0
883 }
884 }
885 }
886
887 #[cfg(feature = "printing")]
888 mod printing {
889 use super::*;
890 use proc_macro2::TokenStream;
891 use quote::{ToTokens, TokenStreamExt};
892
893 impl<T, P> ToTokens for Punctuated<T, P>
894 where
895 T: ToTokens,
896 P: ToTokens,
897 {
to_tokens(&self, tokens: &mut TokenStream)898 fn to_tokens(&self, tokens: &mut TokenStream) {
899 tokens.append_all(self.pairs())
900 }
901 }
902
903 impl<T, P> ToTokens for Pair<T, P>
904 where
905 T: ToTokens,
906 P: ToTokens,
907 {
to_tokens(&self, tokens: &mut TokenStream)908 fn to_tokens(&self, tokens: &mut TokenStream) {
909 match self {
910 Pair::Punctuated(a, b) => {
911 a.to_tokens(tokens);
912 b.to_tokens(tokens);
913 }
914 Pair::End(a) => a.to_tokens(tokens),
915 }
916 }
917 }
918 }
919