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 /// Parses zero or more occurrences of `T` separated by punctuation of type
231 /// `P`, with optional trailing punctuation.
232 ///
233 /// Parsing continues until the end of this parse stream. The entire content
234 /// of this parse stream must consist of `T` and `P`.
235 ///
236 /// *This function is available if Syn is built with the `"parsing"`
237 /// feature.*
238 #[cfg(feature = "parsing")]
parse_terminated(input: ParseStream) -> Result<Self> where T: Parse, P: Parse,239 pub fn parse_terminated(input: ParseStream) -> Result<Self>
240 where
241 T: Parse,
242 P: Parse,
243 {
244 Self::parse_terminated_with(input, T::parse)
245 }
246
247 /// Parses zero or more occurrences of `T` using the given parse function,
248 /// separated by punctuation of type `P`, with optional trailing
249 /// punctuation.
250 ///
251 /// Like [`parse_terminated`], the entire content of this stream is expected
252 /// to be parsed.
253 ///
254 /// [`parse_terminated`]: Punctuated::parse_terminated
255 ///
256 /// *This function is available if Syn is built with the `"parsing"`
257 /// feature.*
258 #[cfg(feature = "parsing")]
parse_terminated_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Parse,259 pub fn parse_terminated_with(
260 input: ParseStream,
261 parser: fn(ParseStream) -> Result<T>,
262 ) -> Result<Self>
263 where
264 P: Parse,
265 {
266 let mut punctuated = Punctuated::new();
267
268 loop {
269 if input.is_empty() {
270 break;
271 }
272 let value = parser(input)?;
273 punctuated.push_value(value);
274 if input.is_empty() {
275 break;
276 }
277 let punct = input.parse()?;
278 punctuated.push_punct(punct);
279 }
280
281 Ok(punctuated)
282 }
283
284 /// Parses one or more occurrences of `T` separated by punctuation of type
285 /// `P`, not accepting trailing punctuation.
286 ///
287 /// Parsing continues as long as punctuation `P` is present at the head of
288 /// the stream. This method returns upon parsing a `T` and observing that it
289 /// is not followed by a `P`, even if there are remaining tokens in the
290 /// stream.
291 ///
292 /// *This function is available if Syn is built with the `"parsing"`
293 /// feature.*
294 #[cfg(feature = "parsing")]
parse_separated_nonempty(input: ParseStream) -> Result<Self> where T: Parse, P: Token + Parse,295 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
296 where
297 T: Parse,
298 P: Token + Parse,
299 {
300 Self::parse_separated_nonempty_with(input, T::parse)
301 }
302
303 /// Parses one or more occurrences of `T` using the given parse function,
304 /// separated by punctuation of type `P`, not accepting trailing
305 /// punctuation.
306 ///
307 /// Like [`parse_separated_nonempty`], may complete early without parsing
308 /// the entire content of this stream.
309 ///
310 /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
311 ///
312 /// *This function is available if Syn is built with the `"parsing"`
313 /// feature.*
314 #[cfg(feature = "parsing")]
parse_separated_nonempty_with( input: ParseStream, parser: fn(ParseStream) -> Result<T>, ) -> Result<Self> where P: Token + Parse,315 pub fn parse_separated_nonempty_with(
316 input: ParseStream,
317 parser: fn(ParseStream) -> Result<T>,
318 ) -> Result<Self>
319 where
320 P: Token + Parse,
321 {
322 let mut punctuated = Punctuated::new();
323
324 loop {
325 let value = parser(input)?;
326 punctuated.push_value(value);
327 if !P::peek(input.cursor()) {
328 break;
329 }
330 let punct = input.parse()?;
331 punctuated.push_punct(punct);
332 }
333
334 Ok(punctuated)
335 }
336 }
337
338 #[cfg(feature = "extra-traits")]
339 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result340 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341 let mut list = f.debug_list();
342 for (t, p) in &self.inner {
343 list.entry(t);
344 list.entry(p);
345 }
346 if let Some(last) = &self.last {
347 list.entry(last);
348 }
349 list.finish()
350 }
351 }
352
353 impl<T, P> FromIterator<T> for Punctuated<T, P>
354 where
355 P: Default,
356 {
from_iter<I: IntoIterator<Item = T>>(i: I) -> Self357 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
358 let mut ret = Punctuated::new();
359 ret.extend(i);
360 ret
361 }
362 }
363
364 impl<T, P> Extend<T> for Punctuated<T, P>
365 where
366 P: Default,
367 {
extend<I: IntoIterator<Item = T>>(&mut self, i: I)368 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
369 for value in i {
370 self.push(value);
371 }
372 }
373 }
374
375 impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self376 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
377 let mut ret = Punctuated::new();
378 ret.extend(i);
379 ret
380 }
381 }
382
383 impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I)384 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
385 assert!(self.empty_or_trailing());
386 let mut nomore = false;
387 for pair in i {
388 if nomore {
389 panic!("Punctuated extended with items after a Pair::End");
390 }
391 match pair {
392 Pair::Punctuated(a, b) => self.inner.push((a, b)),
393 Pair::End(a) => {
394 self.last = Some(Box::new(a));
395 nomore = true;
396 }
397 }
398 }
399 }
400 }
401
402 impl<T, P> IntoIterator for Punctuated<T, P> {
403 type Item = T;
404 type IntoIter = IntoIter<T>;
405
into_iter(self) -> Self::IntoIter406 fn into_iter(self) -> Self::IntoIter {
407 let mut elements = Vec::with_capacity(self.len());
408 elements.extend(self.inner.into_iter().map(|pair| pair.0));
409 elements.extend(self.last.map(|t| *t));
410
411 IntoIter {
412 inner: elements.into_iter(),
413 }
414 }
415 }
416
417 impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
418 type Item = &'a T;
419 type IntoIter = Iter<'a, T>;
420
into_iter(self) -> Self::IntoIter421 fn into_iter(self) -> Self::IntoIter {
422 Punctuated::iter(self)
423 }
424 }
425
426 impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
427 type Item = &'a mut T;
428 type IntoIter = IterMut<'a, T>;
429
into_iter(self) -> Self::IntoIter430 fn into_iter(self) -> Self::IntoIter {
431 Punctuated::iter_mut(self)
432 }
433 }
434
435 impl<T, P> Default for Punctuated<T, P> {
default() -> Self436 fn default() -> Self {
437 Punctuated::new()
438 }
439 }
440
441 /// An iterator over borrowed pairs of type `Pair<&T, &P>`.
442 ///
443 /// Refer to the [module documentation] for details about punctuated sequences.
444 ///
445 /// [module documentation]: self
446 pub struct Pairs<'a, T: 'a, P: 'a> {
447 inner: slice::Iter<'a, (T, P)>,
448 last: option::IntoIter<&'a T>,
449 }
450
451 impl<'a, T, P> Iterator for Pairs<'a, T, P> {
452 type Item = Pair<&'a T, &'a P>;
453
next(&mut self) -> Option<Self::Item>454 fn next(&mut self) -> Option<Self::Item> {
455 self.inner
456 .next()
457 .map(|(t, p)| Pair::Punctuated(t, p))
458 .or_else(|| self.last.next().map(Pair::End))
459 }
460
size_hint(&self) -> (usize, Option<usize>)461 fn size_hint(&self) -> (usize, Option<usize>) {
462 (self.len(), Some(self.len()))
463 }
464 }
465
466 impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>467 fn next_back(&mut self) -> Option<Self::Item> {
468 self.last
469 .next()
470 .map(Pair::End)
471 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
472 }
473 }
474
475 impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
len(&self) -> usize476 fn len(&self) -> usize {
477 self.inner.len() + self.last.len()
478 }
479 }
480
481 // No Clone bound on T or P.
482 impl<'a, T, P> Clone for Pairs<'a, T, P> {
clone(&self) -> Self483 fn clone(&self) -> Self {
484 Pairs {
485 inner: self.inner.clone(),
486 last: self.last.clone(),
487 }
488 }
489 }
490
491 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`.
492 ///
493 /// Refer to the [module documentation] for details about punctuated sequences.
494 ///
495 /// [module documentation]: self
496 pub struct PairsMut<'a, T: 'a, P: 'a> {
497 inner: slice::IterMut<'a, (T, P)>,
498 last: option::IntoIter<&'a mut T>,
499 }
500
501 impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
502 type Item = Pair<&'a mut T, &'a mut P>;
503
next(&mut self) -> Option<Self::Item>504 fn next(&mut self) -> Option<Self::Item> {
505 self.inner
506 .next()
507 .map(|(t, p)| Pair::Punctuated(t, p))
508 .or_else(|| self.last.next().map(Pair::End))
509 }
510
size_hint(&self) -> (usize, Option<usize>)511 fn size_hint(&self) -> (usize, Option<usize>) {
512 (self.len(), Some(self.len()))
513 }
514 }
515
516 impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>517 fn next_back(&mut self) -> Option<Self::Item> {
518 self.last
519 .next()
520 .map(Pair::End)
521 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
522 }
523 }
524
525 impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
len(&self) -> usize526 fn len(&self) -> usize {
527 self.inner.len() + self.last.len()
528 }
529 }
530
531 /// An iterator over owned pairs of type `Pair<T, P>`.
532 ///
533 /// Refer to the [module documentation] for details about punctuated sequences.
534 ///
535 /// [module documentation]: self
536 #[derive(Clone)]
537 pub struct IntoPairs<T, P> {
538 inner: vec::IntoIter<(T, P)>,
539 last: option::IntoIter<T>,
540 }
541
542 impl<T, P> Iterator for IntoPairs<T, P> {
543 type Item = Pair<T, P>;
544
next(&mut self) -> Option<Self::Item>545 fn next(&mut self) -> Option<Self::Item> {
546 self.inner
547 .next()
548 .map(|(t, p)| Pair::Punctuated(t, p))
549 .or_else(|| self.last.next().map(Pair::End))
550 }
551
size_hint(&self) -> (usize, Option<usize>)552 fn size_hint(&self) -> (usize, Option<usize>) {
553 (self.len(), Some(self.len()))
554 }
555 }
556
557 impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
next_back(&mut self) -> Option<Self::Item>558 fn next_back(&mut self) -> Option<Self::Item> {
559 self.last
560 .next()
561 .map(Pair::End)
562 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
563 }
564 }
565
566 impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
len(&self) -> usize567 fn len(&self) -> usize {
568 self.inner.len() + self.last.len()
569 }
570 }
571
572 /// An iterator over owned values of type `T`.
573 ///
574 /// Refer to the [module documentation] for details about punctuated sequences.
575 ///
576 /// [module documentation]: self
577 #[derive(Clone)]
578 pub struct IntoIter<T> {
579 inner: vec::IntoIter<T>,
580 }
581
582 impl<T> Iterator for IntoIter<T> {
583 type Item = T;
584
next(&mut self) -> Option<Self::Item>585 fn next(&mut self) -> Option<Self::Item> {
586 self.inner.next()
587 }
588
size_hint(&self) -> (usize, Option<usize>)589 fn size_hint(&self) -> (usize, Option<usize>) {
590 (self.len(), Some(self.len()))
591 }
592 }
593
594 impl<T> DoubleEndedIterator for IntoIter<T> {
next_back(&mut self) -> Option<Self::Item>595 fn next_back(&mut self) -> Option<Self::Item> {
596 self.inner.next_back()
597 }
598 }
599
600 impl<T> ExactSizeIterator for IntoIter<T> {
len(&self) -> usize601 fn len(&self) -> usize {
602 self.inner.len()
603 }
604 }
605
606 /// An iterator over borrowed values of type `&T`.
607 ///
608 /// Refer to the [module documentation] for details about punctuated sequences.
609 ///
610 /// [module documentation]: self
611 pub struct Iter<'a, T: 'a> {
612 // The `Item = &'a T` needs to be specified to support rustc 1.31 and older.
613 // On modern compilers we would be able to write just IterTrait<'a, T> where
614 // Item can be inferred unambiguously from the supertrait.
615 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
616 }
617
618 trait IterTrait<'a, T: 'a>:
619 DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T>
620 {
clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>621 fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>;
622 }
623
624 struct PrivateIter<'a, T: 'a, P: 'a> {
625 inner: slice::Iter<'a, (T, P)>,
626 last: option::IntoIter<&'a T>,
627 }
628
629 #[cfg(any(feature = "full", feature = "derive"))]
empty_punctuated_iter<'a, T>() -> Iter<'a, T>630 pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
631 Iter {
632 inner: Box::new(iter::empty()),
633 }
634 }
635
636 // No Clone bound on T.
637 impl<'a, T> Clone for Iter<'a, T> {
clone(&self) -> Self638 fn clone(&self) -> Self {
639 Iter {
640 inner: self.inner.clone_box(),
641 }
642 }
643 }
644
645 impl<'a, T> Iterator for Iter<'a, T> {
646 type Item = &'a T;
647
next(&mut self) -> Option<Self::Item>648 fn next(&mut self) -> Option<Self::Item> {
649 self.inner.next()
650 }
651
size_hint(&self) -> (usize, Option<usize>)652 fn size_hint(&self) -> (usize, Option<usize>) {
653 (self.len(), Some(self.len()))
654 }
655 }
656
657 impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
next_back(&mut self) -> Option<Self::Item>658 fn next_back(&mut self) -> Option<Self::Item> {
659 self.inner.next_back()
660 }
661 }
662
663 impl<'a, T> ExactSizeIterator for Iter<'a, T> {
len(&self) -> usize664 fn len(&self) -> usize {
665 self.inner.len()
666 }
667 }
668
669 impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
670 type Item = &'a T;
671
next(&mut self) -> Option<Self::Item>672 fn next(&mut self) -> Option<Self::Item> {
673 self.inner
674 .next()
675 .map(|pair| &pair.0)
676 .or_else(|| self.last.next())
677 }
678 }
679
680 impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>681 fn next_back(&mut self) -> Option<Self::Item> {
682 self.last
683 .next()
684 .or_else(|| self.inner.next_back().map(|pair| &pair.0))
685 }
686 }
687
688 impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
len(&self) -> usize689 fn len(&self) -> usize {
690 self.inner.len() + self.last.len()
691 }
692 }
693
694 // No Clone bound on T or P.
695 impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
clone(&self) -> Self696 fn clone(&self) -> Self {
697 PrivateIter {
698 inner: self.inner.clone(),
699 last: self.last.clone(),
700 }
701 }
702 }
703
704 impl<'a, T: 'a, I: 'a> IterTrait<'a, T> for I
705 where
706 I: DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T> + Clone,
707 {
clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>708 fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a> {
709 Box::new(self.clone())
710 }
711 }
712
713 /// An iterator over mutably borrowed values of type `&mut T`.
714 ///
715 /// Refer to the [module documentation] for details about punctuated sequences.
716 ///
717 /// [module documentation]: self
718 pub struct IterMut<'a, T: 'a> {
719 inner: Box<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>,
720 }
721
722 trait IterMutTrait<'a, T: 'a>:
723 DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
724 {
725 }
726
727 struct PrivateIterMut<'a, T: 'a, P: 'a> {
728 inner: slice::IterMut<'a, (T, P)>,
729 last: option::IntoIter<&'a mut T>,
730 }
731
732 #[cfg(any(feature = "full", feature = "derive"))]
empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T>733 pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
734 IterMut {
735 inner: Box::new(iter::empty()),
736 }
737 }
738
739 impl<'a, T> Iterator for IterMut<'a, T> {
740 type Item = &'a mut T;
741
next(&mut self) -> Option<Self::Item>742 fn next(&mut self) -> Option<Self::Item> {
743 self.inner.next()
744 }
745
size_hint(&self) -> (usize, Option<usize>)746 fn size_hint(&self) -> (usize, Option<usize>) {
747 (self.len(), Some(self.len()))
748 }
749 }
750
751 impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
next_back(&mut self) -> Option<Self::Item>752 fn next_back(&mut self) -> Option<Self::Item> {
753 self.inner.next_back()
754 }
755 }
756
757 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
len(&self) -> usize758 fn len(&self) -> usize {
759 self.inner.len()
760 }
761 }
762
763 impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
764 type Item = &'a mut T;
765
next(&mut self) -> Option<Self::Item>766 fn next(&mut self) -> Option<Self::Item> {
767 self.inner
768 .next()
769 .map(|pair| &mut pair.0)
770 .or_else(|| self.last.next())
771 }
772 }
773
774 impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
next_back(&mut self) -> Option<Self::Item>775 fn next_back(&mut self) -> Option<Self::Item> {
776 self.last
777 .next()
778 .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
779 }
780 }
781
782 impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
len(&self) -> usize783 fn len(&self) -> usize {
784 self.inner.len() + self.last.len()
785 }
786 }
787
788 impl<'a, T: 'a, I: 'a> IterMutTrait<'a, T> for I where
789 I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
790 {
791 }
792
793 /// A single syntax tree node of type `T` followed by its trailing punctuation
794 /// of type `P` if any.
795 ///
796 /// Refer to the [module documentation] for details about punctuated sequences.
797 ///
798 /// [module documentation]: self
799 #[cfg_attr(feature = "clone-impls", derive(Clone))]
800 pub enum Pair<T, P> {
801 Punctuated(T, P),
802 End(T),
803 }
804
805 impl<T, P> Pair<T, P> {
806 /// Extracts the syntax tree node from this punctuated pair, discarding the
807 /// following punctuation.
into_value(self) -> T808 pub fn into_value(self) -> T {
809 match self {
810 Pair::Punctuated(t, _) | Pair::End(t) => t,
811 }
812 }
813
814 /// Borrows the syntax tree node from this punctuated pair.
value(&self) -> &T815 pub fn value(&self) -> &T {
816 match self {
817 Pair::Punctuated(t, _) | Pair::End(t) => t,
818 }
819 }
820
821 /// Mutably borrows the syntax tree node from this punctuated pair.
value_mut(&mut self) -> &mut T822 pub fn value_mut(&mut self) -> &mut T {
823 match self {
824 Pair::Punctuated(t, _) | Pair::End(t) => t,
825 }
826 }
827
828 /// Borrows the punctuation from this punctuated pair, unless this pair is
829 /// the final one and there is no trailing punctuation.
punct(&self) -> Option<&P>830 pub fn punct(&self) -> Option<&P> {
831 match self {
832 Pair::Punctuated(_, d) => Some(d),
833 Pair::End(_) => None,
834 }
835 }
836
837 /// Creates a punctuated pair out of a syntax tree node and an optional
838 /// following punctuation.
new(t: T, d: Option<P>) -> Self839 pub fn new(t: T, d: Option<P>) -> Self {
840 match d {
841 Some(d) => Pair::Punctuated(t, d),
842 None => Pair::End(t),
843 }
844 }
845
846 /// Produces this punctuated pair as a tuple of syntax tree node and
847 /// optional following punctuation.
into_tuple(self) -> (T, Option<P>)848 pub fn into_tuple(self) -> (T, Option<P>) {
849 match self {
850 Pair::Punctuated(t, d) => (t, Some(d)),
851 Pair::End(t) => (t, None),
852 }
853 }
854 }
855
856 impl<T, P> Index<usize> for Punctuated<T, P> {
857 type Output = T;
858
index(&self, index: usize) -> &Self::Output859 fn index(&self, index: usize) -> &Self::Output {
860 if index == self.len() - 1 {
861 match &self.last {
862 Some(t) => t,
863 None => &self.inner[index].0,
864 }
865 } else {
866 &self.inner[index].0
867 }
868 }
869 }
870
871 impl<T, P> IndexMut<usize> for Punctuated<T, P> {
index_mut(&mut self, index: usize) -> &mut Self::Output872 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
873 if index == self.len() - 1 {
874 match &mut self.last {
875 Some(t) => t,
876 None => &mut self.inner[index].0,
877 }
878 } else {
879 &mut self.inner[index].0
880 }
881 }
882 }
883
884 #[cfg(feature = "printing")]
885 mod printing {
886 use super::*;
887 use proc_macro2::TokenStream;
888 use quote::{ToTokens, TokenStreamExt};
889
890 impl<T, P> ToTokens for Punctuated<T, P>
891 where
892 T: ToTokens,
893 P: ToTokens,
894 {
to_tokens(&self, tokens: &mut TokenStream)895 fn to_tokens(&self, tokens: &mut TokenStream) {
896 tokens.append_all(self.pairs())
897 }
898 }
899
900 impl<T, P> ToTokens for Pair<T, P>
901 where
902 T: ToTokens,
903 P: ToTokens,
904 {
to_tokens(&self, tokens: &mut TokenStream)905 fn to_tokens(&self, tokens: &mut TokenStream) {
906 match self {
907 Pair::Punctuated(a, b) => {
908 a.to_tokens(tokens);
909 b.to_tokens(tokens);
910 }
911 Pair::End(a) => a.to_tokens(tokens),
912 }
913 }
914 }
915 }
916