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