1use crate::drops::{NoDrop, TrivialDrop};
24#[cfg(feature = "parsing")]
25use crate::error::Result;
26#[cfg(feature = "parsing")]
27use crate::parse::{Parse, ParseStream};
28#[cfg(feature = "parsing")]
29use crate::token::Token;
30use alloc::boxed::Box;
31#[cfg(all(feature = "fold", any(feature = "full", feature = "derive")))]
32use alloc::collections::VecDeque;
33use alloc::vec::{self, Vec};
34#[cfg(feature = "extra-traits")]
35use core::fmt::{self, Debug};
36#[cfg(feature = "extra-traits")]
37use core::hash::{Hash, Hasher};
38#[cfg(any(feature = "full", feature = "derive"))]
39use core::iter;
40use core::ops::{Index, IndexMut};
41use core::option;
42use core::slice;
43
44pub struct Punctuated<T, P> {
51 inner: Vec<(T, P)>,
52 last: Option<Box<T>>,
53}
54
55impl<T, P> Punctuated<T, P> {
56 pub const fn new() -> Self {
58 Punctuated {
59 inner: Vec::new(),
60 last: None,
61 }
62 }
63
64 pub fn is_empty(&self) -> bool {
67 self.inner.len() == 0 && self.last.is_none()
68 }
69
70 pub fn len(&self) -> usize {
75 self.inner.len() + if self.last.is_some() { 1 } else { 0 }
76 }
77
78 pub fn first(&self) -> Option<&T> {
80 self.iter().next()
81 }
82
83 pub fn first_mut(&mut self) -> Option<&mut T> {
85 self.iter_mut().next()
86 }
87
88 pub fn last(&self) -> Option<&T> {
90 self.iter().next_back()
91 }
92
93 pub fn last_mut(&mut self) -> Option<&mut T> {
95 self.iter_mut().next_back()
96 }
97
98 pub fn get(&self, index: usize) -> Option<&T> {
100 if let Some((value, _punct)) = self.inner.get(index) {
101 Some(value)
102 } else if index == self.inner.len() {
103 self.last.as_deref()
104 } else {
105 None
106 }
107 }
108
109 pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
111 let inner_len = self.inner.len();
112 if let Some((value, _punct)) = self.inner.get_mut(index) {
113 Some(value)
114 } else if index == inner_len {
115 self.last.as_deref_mut()
116 } else {
117 None
118 }
119 }
120
121 pub fn iter(&self) -> Iter<T> {
123 Iter {
124 inner: Box::new(NoDrop::new(PrivateIter {
125 inner: self.inner.iter(),
126 last: self.last.as_ref().map(Box::as_ref).into_iter(),
127 })),
128 }
129 }
130
131 pub fn iter_mut(&mut self) -> IterMut<T> {
134 IterMut {
135 inner: Box::new(NoDrop::new(PrivateIterMut {
136 inner: self.inner.iter_mut(),
137 last: self.last.as_mut().map(Box::as_mut).into_iter(),
138 })),
139 }
140 }
141
142 pub fn pairs(&self) -> Pairs<T, P> {
145 Pairs {
146 inner: self.inner.iter(),
147 last: self.last.as_ref().map(Box::as_ref).into_iter(),
148 }
149 }
150
151 pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
154 PairsMut {
155 inner: self.inner.iter_mut(),
156 last: self.last.as_mut().map(Box::as_mut).into_iter(),
157 }
158 }
159
160 pub fn into_pairs(self) -> IntoPairs<T, P> {
163 IntoPairs {
164 inner: self.inner.into_iter(),
165 last: self.last.map(|t| *t).into_iter(),
166 }
167 }
168
169 pub fn push_value(&mut self, value: T) {
182 assert!(
183 self.empty_or_trailing(),
184 "Punctuated::push_value: cannot push value if Punctuated is missing trailing punctuation",
185 );
186
187 self.last = Some(Box::new(value));
188 }
189
190 pub fn push_punct(&mut self, punctuation: P) {
198 assert!(
199 self.last.is_some(),
200 "Punctuated::push_punct: cannot push punctuation if Punctuated is empty or already has trailing punctuation",
201 );
202
203 let last = self.last.take().unwrap();
204 self.inner.push((*last, punctuation));
205 }
206
207 pub fn pop(&mut self) -> Option<Pair<T, P>> {
210 if self.last.is_some() {
211 self.last.take().map(|t| Pair::End(*t))
212 } else {
213 self.inner.pop().map(|(t, p)| Pair::Punctuated(t, p))
214 }
215 }
216
217 pub fn pop_punct(&mut self) -> Option<P> {
220 if self.last.is_some() {
221 None
222 } else {
223 let (t, p) = self.inner.pop()?;
224 self.last = Some(Box::new(t));
225 Some(p)
226 }
227 }
228
229 pub fn trailing_punct(&self) -> bool {
232 self.last.is_none() && !self.is_empty()
233 }
234
235 pub fn empty_or_trailing(&self) -> bool {
240 self.last.is_none()
241 }
242
243 pub fn push(&mut self, value: T)
249 where
250 P: Default,
251 {
252 if !self.empty_or_trailing() {
253 self.push_punct(Default::default());
254 }
255 self.push_value(value);
256 }
257
258 pub fn insert(&mut self, index: usize, value: T)
265 where
266 P: Default,
267 {
268 assert!(
269 index <= self.len(),
270 "Punctuated::insert: index out of range",
271 );
272
273 if index == self.len() {
274 self.push(value);
275 } else {
276 self.inner.insert(index, (value, Default::default()));
277 }
278 }
279
280 pub fn clear(&mut self) {
282 self.inner.clear();
283 self.last = None;
284 }
285
286 #[cfg(feature = "parsing")]
292 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
293 pub fn parse_terminated(input: ParseStream) -> Result<Self>
294 where
295 T: Parse,
296 P: Parse,
297 {
298 Self::parse_terminated_with(input, T::parse)
299 }
300
301 #[cfg(feature = "parsing")]
310 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
311 pub fn parse_terminated_with<'a>(
312 input: ParseStream<'a>,
313 parser: fn(ParseStream<'a>) -> Result<T>,
314 ) -> Result<Self>
315 where
316 P: Parse,
317 {
318 let mut punctuated = Punctuated::new();
319
320 loop {
321 if input.is_empty() {
322 break;
323 }
324 let value = parser(input)?;
325 punctuated.push_value(value);
326 if input.is_empty() {
327 break;
328 }
329 let punct = input.parse()?;
330 punctuated.push_punct(punct);
331 }
332
333 Ok(punctuated)
334 }
335
336 #[cfg(feature = "parsing")]
344 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
345 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
346 where
347 T: Parse,
348 P: Token + Parse,
349 {
350 Self::parse_separated_nonempty_with(input, T::parse)
351 }
352
353 #[cfg(feature = "parsing")]
362 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
363 pub fn parse_separated_nonempty_with<'a>(
364 input: ParseStream<'a>,
365 parser: fn(ParseStream<'a>) -> Result<T>,
366 ) -> Result<Self>
367 where
368 P: Token + Parse,
369 {
370 let mut punctuated = Punctuated::new();
371
372 loop {
373 let value = parser(input)?;
374 punctuated.push_value(value);
375 if !P::peek(input.cursor()) {
376 break;
377 }
378 let punct = input.parse()?;
379 punctuated.push_punct(punct);
380 }
381
382 Ok(punctuated)
383 }
384}
385
386#[cfg(feature = "clone-impls")]
387#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
388impl<T, P> Clone for Punctuated<T, P>
389where
390 T: Clone,
391 P: Clone,
392{
393 fn clone(&self) -> Self {
394 Punctuated {
395 inner: self.inner.clone(),
396 last: self.last.clone(),
397 }
398 }
399
400 fn clone_from(&mut self, other: &Self) {
401 self.inner.clone_from(&other.inner);
402 self.last.clone_from(&other.last);
403 }
404}
405
406#[cfg(feature = "extra-traits")]
407#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
408impl<T, P> Eq for Punctuated<T, P>
409where
410 T: Eq,
411 P: Eq,
412{
413}
414
415#[cfg(feature = "extra-traits")]
416#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
417impl<T, P> PartialEq for Punctuated<T, P>
418where
419 T: PartialEq,
420 P: PartialEq,
421{
422 fn eq(&self, other: &Self) -> bool {
423 let Punctuated { inner, last } = self;
424 *inner == other.inner && *last == other.last
425 }
426}
427
428#[cfg(feature = "extra-traits")]
429#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
430impl<T, P> Hash for Punctuated<T, P>
431where
432 T: Hash,
433 P: Hash,
434{
435 fn hash<H: Hasher>(&self, state: &mut H) {
436 let Punctuated { inner, last } = self;
437 inner.hash(state);
438 last.hash(state);
439 }
440}
441
442#[cfg(feature = "extra-traits")]
443#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
444impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
445 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
446 let mut list = f.debug_list();
447 for (t, p) in &self.inner {
448 list.entry(t);
449 list.entry(p);
450 }
451 if let Some(last) = &self.last {
452 list.entry(last);
453 }
454 list.finish()
455 }
456}
457
458impl<T, P> FromIterator<T> for Punctuated<T, P>
459where
460 P: Default,
461{
462 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
463 let mut ret = Punctuated::new();
464 ret.extend(i);
465 ret
466 }
467}
468
469impl<T, P> Extend<T> for Punctuated<T, P>
470where
471 P: Default,
472{
473 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
474 for value in i {
475 self.push(value);
476 }
477 }
478}
479
480impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
481 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
482 let mut ret = Punctuated::new();
483 do_extend(&mut ret, i.into_iter());
484 ret
485 }
486}
487
488impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P>
489where
490 P: Default,
491{
492 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
493 if !self.empty_or_trailing() {
494 self.push_punct(P::default());
495 }
496 do_extend(self, i.into_iter());
497 }
498}
499
500fn do_extend<T, P, I>(punctuated: &mut Punctuated<T, P>, i: I)
501where
502 I: Iterator<Item = Pair<T, P>>,
503{
504 let mut nomore = false;
505 for pair in i {
506 if nomore {
507 panic!("punctuated extended with items after a Pair::End");
508 }
509 match pair {
510 Pair::Punctuated(a, b) => punctuated.inner.push((a, b)),
511 Pair::End(a) => {
512 punctuated.last = Some(Box::new(a));
513 nomore = true;
514 }
515 }
516 }
517}
518
519impl<T, P> IntoIterator for Punctuated<T, P> {
520 type Item = T;
521 type IntoIter = IntoIter<T>;
522
523 fn into_iter(self) -> Self::IntoIter {
524 let mut elements = Vec::with_capacity(self.len());
525
526 for (t, _) in self.inner {
527 elements.push(t);
528 }
529 if let Some(t) = self.last {
530 elements.push(*t);
531 }
532
533 IntoIter {
534 inner: elements.into_iter(),
535 }
536 }
537}
538
539impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
540 type Item = &'a T;
541 type IntoIter = Iter<'a, T>;
542
543 fn into_iter(self) -> Self::IntoIter {
544 Punctuated::iter(self)
545 }
546}
547
548impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
549 type Item = &'a mut T;
550 type IntoIter = IterMut<'a, T>;
551
552 fn into_iter(self) -> Self::IntoIter {
553 Punctuated::iter_mut(self)
554 }
555}
556
557impl<T, P> Default for Punctuated<T, P> {
558 fn default() -> Self {
559 Punctuated::new()
560 }
561}
562
563pub struct Pairs<'a, T: 'a, P: 'a> {
569 inner: slice::Iter<'a, (T, P)>,
570 last: option::IntoIter<&'a T>,
571}
572
573impl<'a, T, P> Iterator for Pairs<'a, T, P> {
574 type Item = Pair<&'a T, &'a P>;
575
576 fn next(&mut self) -> Option<Self::Item> {
577 self.inner
578 .next()
579 .map(|(t, p)| Pair::Punctuated(t, p))
580 .or_else(|| self.last.next().map(Pair::End))
581 }
582
583 fn size_hint(&self) -> (usize, Option<usize>) {
584 (self.len(), Some(self.len()))
585 }
586}
587
588impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
589 fn next_back(&mut self) -> Option<Self::Item> {
590 self.last
591 .next()
592 .map(Pair::End)
593 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
594 }
595}
596
597impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
598 fn len(&self) -> usize {
599 self.inner.len() + self.last.len()
600 }
601}
602
603impl<'a, T, P> Clone for Pairs<'a, T, P> {
605 fn clone(&self) -> Self {
606 Pairs {
607 inner: self.inner.clone(),
608 last: self.last.clone(),
609 }
610 }
611}
612
613pub struct PairsMut<'a, T: 'a, P: 'a> {
619 inner: slice::IterMut<'a, (T, P)>,
620 last: option::IntoIter<&'a mut T>,
621}
622
623impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
624 type Item = Pair<&'a mut T, &'a mut P>;
625
626 fn next(&mut self) -> Option<Self::Item> {
627 self.inner
628 .next()
629 .map(|(t, p)| Pair::Punctuated(t, p))
630 .or_else(|| self.last.next().map(Pair::End))
631 }
632
633 fn size_hint(&self) -> (usize, Option<usize>) {
634 (self.len(), Some(self.len()))
635 }
636}
637
638impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
639 fn next_back(&mut self) -> Option<Self::Item> {
640 self.last
641 .next()
642 .map(Pair::End)
643 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
644 }
645}
646
647impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
648 fn len(&self) -> usize {
649 self.inner.len() + self.last.len()
650 }
651}
652
653pub struct IntoPairs<T, P> {
659 inner: vec::IntoIter<(T, P)>,
660 last: option::IntoIter<T>,
661}
662
663impl<T, P> Iterator for IntoPairs<T, P> {
664 type Item = Pair<T, P>;
665
666 fn next(&mut self) -> Option<Self::Item> {
667 self.inner
668 .next()
669 .map(|(t, p)| Pair::Punctuated(t, p))
670 .or_else(|| self.last.next().map(Pair::End))
671 }
672
673 fn size_hint(&self) -> (usize, Option<usize>) {
674 (self.len(), Some(self.len()))
675 }
676}
677
678impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
679 fn next_back(&mut self) -> Option<Self::Item> {
680 self.last
681 .next()
682 .map(Pair::End)
683 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
684 }
685}
686
687impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
688 fn len(&self) -> usize {
689 self.inner.len() + self.last.len()
690 }
691}
692
693impl<T, P> Clone for IntoPairs<T, P>
694where
695 T: Clone,
696 P: Clone,
697{
698 fn clone(&self) -> Self {
699 IntoPairs {
700 inner: self.inner.clone(),
701 last: self.last.clone(),
702 }
703 }
704}
705
706pub struct IntoIter<T> {
712 inner: vec::IntoIter<T>,
713}
714
715impl<T> Iterator for IntoIter<T> {
716 type Item = T;
717
718 fn next(&mut self) -> Option<Self::Item> {
719 self.inner.next()
720 }
721
722 fn size_hint(&self) -> (usize, Option<usize>) {
723 (self.len(), Some(self.len()))
724 }
725}
726
727impl<T> DoubleEndedIterator for IntoIter<T> {
728 fn next_back(&mut self) -> Option<Self::Item> {
729 self.inner.next_back()
730 }
731}
732
733impl<T> ExactSizeIterator for IntoIter<T> {
734 fn len(&self) -> usize {
735 self.inner.len()
736 }
737}
738
739impl<T> Clone for IntoIter<T>
740where
741 T: Clone,
742{
743 fn clone(&self) -> Self {
744 IntoIter {
745 inner: self.inner.clone(),
746 }
747 }
748}
749
750pub struct Iter<'a, T: 'a> {
756 inner: Box<NoDrop<dyn IterTrait<'a, T> + 'a>>,
757}
758
759trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> + DoubleEndedIterator + ExactSizeIterator {
760 fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>>;
761}
762
763struct PrivateIter<'a, T: 'a, P: 'a> {
764 inner: slice::Iter<'a, (T, P)>,
765 last: option::IntoIter<&'a T>,
766}
767
768impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
769where
770 slice::Iter<'a, (T, P)>: TrivialDrop,
771 option::IntoIter<&'a T>: TrivialDrop,
772{
773}
774
775#[cfg(any(feature = "full", feature = "derive"))]
776pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
777 Iter {
778 inner: Box::new(NoDrop::new(iter::empty())),
779 }
780}
781
782impl<'a, T> Clone for Iter<'a, T> {
784 fn clone(&self) -> Self {
785 Iter {
786 inner: self.inner.clone_box(),
787 }
788 }
789}
790
791impl<'a, T> Iterator for Iter<'a, T> {
792 type Item = &'a T;
793
794 fn next(&mut self) -> Option<Self::Item> {
795 self.inner.next()
796 }
797
798 fn size_hint(&self) -> (usize, Option<usize>) {
799 (self.len(), Some(self.len()))
800 }
801}
802
803impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
804 fn next_back(&mut self) -> Option<Self::Item> {
805 self.inner.next_back()
806 }
807}
808
809impl<'a, T> ExactSizeIterator for Iter<'a, T> {
810 fn len(&self) -> usize {
811 self.inner.len()
812 }
813}
814
815impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
816 type Item = &'a T;
817
818 fn next(&mut self) -> Option<Self::Item> {
819 self.inner
820 .next()
821 .map(|pair| &pair.0)
822 .or_else(|| self.last.next())
823 }
824}
825
826impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
827 fn next_back(&mut self) -> Option<Self::Item> {
828 self.last
829 .next()
830 .or_else(|| self.inner.next_back().map(|pair| &pair.0))
831 }
832}
833
834impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
835 fn len(&self) -> usize {
836 self.inner.len() + self.last.len()
837 }
838}
839
840impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
842 fn clone(&self) -> Self {
843 PrivateIter {
844 inner: self.inner.clone(),
845 last: self.last.clone(),
846 }
847 }
848}
849
850impl<'a, T, I> IterTrait<'a, T> for I
851where
852 T: 'a,
853 I: DoubleEndedIterator<Item = &'a T>
854 + ExactSizeIterator<Item = &'a T>
855 + Clone
856 + TrivialDrop
857 + 'a,
858{
859 fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>> {
860 Box::new(NoDrop::new(self.clone()))
861 }
862}
863
864pub struct IterMut<'a, T: 'a> {
870 inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
871}
872
873trait IterMutTrait<'a, T: 'a>:
874 DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
875{
876}
877
878struct PrivateIterMut<'a, T: 'a, P: 'a> {
879 inner: slice::IterMut<'a, (T, P)>,
880 last: option::IntoIter<&'a mut T>,
881}
882
883impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
884where
885 slice::IterMut<'a, (T, P)>: TrivialDrop,
886 option::IntoIter<&'a mut T>: TrivialDrop,
887{
888}
889
890#[cfg(any(feature = "full", feature = "derive"))]
891pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
892 IterMut {
893 inner: Box::new(NoDrop::new(iter::empty())),
894 }
895}
896
897impl<'a, T> Iterator for IterMut<'a, T> {
898 type Item = &'a mut T;
899
900 fn next(&mut self) -> Option<Self::Item> {
901 self.inner.next()
902 }
903
904 fn size_hint(&self) -> (usize, Option<usize>) {
905 (self.len(), Some(self.len()))
906 }
907}
908
909impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
910 fn next_back(&mut self) -> Option<Self::Item> {
911 self.inner.next_back()
912 }
913}
914
915impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
916 fn len(&self) -> usize {
917 self.inner.len()
918 }
919}
920
921impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
922 type Item = &'a mut T;
923
924 fn next(&mut self) -> Option<Self::Item> {
925 self.inner
926 .next()
927 .map(|pair| &mut pair.0)
928 .or_else(|| self.last.next())
929 }
930}
931
932impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
933 fn next_back(&mut self) -> Option<Self::Item> {
934 self.last
935 .next()
936 .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
937 }
938}
939
940impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
941 fn len(&self) -> usize {
942 self.inner.len() + self.last.len()
943 }
944}
945
946impl<'a, T, I> IterMutTrait<'a, T> for I
947where
948 T: 'a,
949 I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T> + 'a,
950{
951}
952
953pub enum Pair<T, P> {
960 Punctuated(T, P),
961 End(T),
962}
963
964impl<T, P> Pair<T, P> {
965 pub fn into_value(self) -> T {
968 match self {
969 Pair::Punctuated(t, _) | Pair::End(t) => t,
970 }
971 }
972
973 pub fn value(&self) -> &T {
975 match self {
976 Pair::Punctuated(t, _) | Pair::End(t) => t,
977 }
978 }
979
980 pub fn value_mut(&mut self) -> &mut T {
982 match self {
983 Pair::Punctuated(t, _) | Pair::End(t) => t,
984 }
985 }
986
987 pub fn punct(&self) -> Option<&P> {
990 match self {
991 Pair::Punctuated(_, p) => Some(p),
992 Pair::End(_) => None,
993 }
994 }
995
996 pub fn punct_mut(&mut self) -> Option<&mut P> {
1015 match self {
1016 Pair::Punctuated(_, p) => Some(p),
1017 Pair::End(_) => None,
1018 }
1019 }
1020
1021 pub fn new(t: T, p: Option<P>) -> Self {
1024 match p {
1025 Some(p) => Pair::Punctuated(t, p),
1026 None => Pair::End(t),
1027 }
1028 }
1029
1030 pub fn into_tuple(self) -> (T, Option<P>) {
1033 match self {
1034 Pair::Punctuated(t, p) => (t, Some(p)),
1035 Pair::End(t) => (t, None),
1036 }
1037 }
1038}
1039
1040#[cfg(feature = "clone-impls")]
1041#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1042impl<T, P> Pair<&T, &P> {
1043 pub fn cloned(self) -> Pair<T, P>
1044 where
1045 T: Clone,
1046 P: Clone,
1047 {
1048 match self {
1049 Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
1050 Pair::End(t) => Pair::End(t.clone()),
1051 }
1052 }
1053}
1054
1055#[cfg(feature = "clone-impls")]
1056#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1057impl<T, P> Clone for Pair<T, P>
1058where
1059 T: Clone,
1060 P: Clone,
1061{
1062 fn clone(&self) -> Self {
1063 match self {
1064 Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
1065 Pair::End(t) => Pair::End(t.clone()),
1066 }
1067 }
1068}
1069
1070#[cfg(feature = "clone-impls")]
1071#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1072impl<T, P> Copy for Pair<T, P>
1073where
1074 T: Copy,
1075 P: Copy,
1076{
1077}
1078
1079impl<T, P> Index<usize> for Punctuated<T, P> {
1080 type Output = T;
1081
1082 fn index(&self, index: usize) -> &Self::Output {
1083 if index.checked_add(1) == Some(self.len()) {
1084 match &self.last {
1085 Some(t) => t,
1086 None => &self.inner[index].0,
1087 }
1088 } else {
1089 &self.inner[index].0
1090 }
1091 }
1092}
1093
1094impl<T, P> IndexMut<usize> for Punctuated<T, P> {
1095 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1096 if index.checked_add(1) == Some(self.len()) {
1097 match &mut self.last {
1098 Some(t) => t,
1099 None => &mut self.inner[index].0,
1100 }
1101 } else {
1102 &mut self.inner[index].0
1103 }
1104 }
1105}
1106
1107#[cfg(all(feature = "fold", any(feature = "full", feature = "derive")))]
1108pub(crate) fn fold<T, P, V, F>(
1109 punctuated: Punctuated<T, P>,
1110 fold: &mut V,
1111 mut f: F,
1112) -> Punctuated<T, P>
1113where
1114 V: ?Sized,
1115 F: FnMut(&mut V, T) -> T,
1116{
1117 let Punctuated { inner, last } = punctuated;
1118
1119 let mut inner = VecDeque::from(inner);
1122 for _ in 0..inner.len() {
1123 if let Some((t, p)) = inner.pop_front() {
1124 inner.push_back((f(fold, t), p));
1125 }
1126 }
1127
1128 Punctuated {
1129 inner: Vec::from(inner),
1130 last: match last {
1131 Some(t) => Some(Box::new(f(fold, *t))),
1132 None => None,
1133 },
1134 }
1135}
1136
1137#[cfg(feature = "printing")]
1138mod printing {
1139 use crate::punctuated::{Pair, Punctuated};
1140 use proc_macro2::TokenStream;
1141 use quote::{ToTokens, TokenStreamExt as _};
1142
1143 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1144 impl<T, P> ToTokens for Punctuated<T, P>
1145 where
1146 T: ToTokens,
1147 P: ToTokens,
1148 {
1149 fn to_tokens(&self, tokens: &mut TokenStream) {
1150 tokens.append_all(self.pairs());
1151 }
1152 }
1153
1154 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1155 impl<T, P> ToTokens for Pair<T, P>
1156 where
1157 T: ToTokens,
1158 P: ToTokens,
1159 {
1160 fn to_tokens(&self, tokens: &mut TokenStream) {
1161 match self {
1162 Pair::Punctuated(a, b) => {
1163 a.to_tokens(tokens);
1164 b.to_tokens(tokens);
1165 }
1166 Pair::End(a) => a.to_tokens(tokens),
1167 }
1168 }
1169 }
1170}