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