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<T> {
210 if self.last.is_some() {
211 self.last.take().map(|t| *t)
212 } else {
213 self.inner.pop().map(|(t, _p)| t)
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 pop_pair(&mut self) -> Option<Pair<T, P>> {
232 if self.last.is_some() {
233 self.last.take().map(|t| Pair::End(*t))
234 } else {
235 self.inner.pop().map(|(t, p)| Pair::Punctuated(t, p))
236 }
237 }
238
239 pub fn trailing_punct(&self) -> bool {
242 self.last.is_none() && !self.is_empty()
243 }
244
245 pub fn empty_or_trailing(&self) -> bool {
250 self.last.is_none()
251 }
252
253 pub fn push(&mut self, value: T)
259 where
260 P: Default,
261 {
262 if !self.empty_or_trailing() {
263 self.push_punct(Default::default());
264 }
265 self.push_value(value);
266 }
267
268 pub fn insert(&mut self, index: usize, value: T)
275 where
276 P: Default,
277 {
278 assert!(
279 index <= self.len(),
280 "Punctuated::insert: index out of range",
281 );
282
283 if index == self.len() {
284 self.push(value);
285 } else {
286 self.inner.insert(index, (value, Default::default()));
287 }
288 }
289
290 pub fn clear(&mut self) {
292 self.inner.clear();
293 self.last = None;
294 }
295
296 pub fn retain<F>(&mut self, mut f: F)
301 where
302 F: FnMut(&mut T) -> bool,
303 {
304 self.inner.retain_mut(|(t, _p)| f(t));
305 if let Some(last) = &mut self.last {
306 if !f(last) {
307 if let Some((second_last, _p)) = self.inner.pop() {
308 **last = second_last;
309 } else {
310 self.last = None;
311 }
312 }
313 }
314 }
315
316 #[cfg(feature = "parsing")]
322 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
323 pub fn parse_terminated(input: ParseStream) -> Result<Self>
324 where
325 T: Parse,
326 P: Parse,
327 {
328 Self::parse_terminated_with(input, T::parse)
329 }
330
331 #[cfg(feature = "parsing")]
340 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
341 pub fn parse_terminated_with<'a>(
342 input: ParseStream<'a>,
343 parser: fn(ParseStream<'a>) -> Result<T>,
344 ) -> Result<Self>
345 where
346 P: Parse,
347 {
348 let mut punctuated = Punctuated::new();
349
350 loop {
351 if input.is_empty() {
352 break;
353 }
354 let value = parser(input)?;
355 punctuated.push_value(value);
356 if input.is_empty() {
357 break;
358 }
359 let punct = input.parse()?;
360 punctuated.push_punct(punct);
361 }
362
363 Ok(punctuated)
364 }
365
366 #[cfg(feature = "parsing")]
374 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
375 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
376 where
377 T: Parse,
378 P: Token + Parse,
379 {
380 Self::parse_separated_nonempty_with(input, T::parse)
381 }
382
383 #[cfg(feature = "parsing")]
392 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
393 pub fn parse_separated_nonempty_with<'a>(
394 input: ParseStream<'a>,
395 parser: fn(ParseStream<'a>) -> Result<T>,
396 ) -> Result<Self>
397 where
398 P: Token + Parse,
399 {
400 let mut punctuated = Punctuated::new();
401
402 loop {
403 let value = parser(input)?;
404 punctuated.push_value(value);
405 if !P::peek(input.cursor()) {
406 break;
407 }
408 let punct = input.parse()?;
409 punctuated.push_punct(punct);
410 }
411
412 Ok(punctuated)
413 }
414}
415
416#[cfg(feature = "clone-impls")]
417#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
418impl<T, P> Clone for Punctuated<T, P>
419where
420 T: Clone,
421 P: Clone,
422{
423 fn clone(&self) -> Self {
424 Punctuated {
425 inner: self.inner.clone(),
426 last: self.last.clone(),
427 }
428 }
429
430 fn clone_from(&mut self, other: &Self) {
431 self.inner.clone_from(&other.inner);
432 self.last.clone_from(&other.last);
433 }
434}
435
436#[cfg(feature = "extra-traits")]
437#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
438impl<T, P> Eq for Punctuated<T, P>
439where
440 T: Eq,
441 P: Eq,
442{
443}
444
445#[cfg(feature = "extra-traits")]
446#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
447impl<T, P> PartialEq for Punctuated<T, P>
448where
449 T: PartialEq,
450 P: PartialEq,
451{
452 fn eq(&self, other: &Self) -> bool {
453 let Punctuated { inner, last } = self;
454 *inner == other.inner && *last == other.last
455 }
456}
457
458#[cfg(feature = "extra-traits")]
459#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
460impl<T, P> Hash for Punctuated<T, P>
461where
462 T: Hash,
463 P: Hash,
464{
465 fn hash<H: Hasher>(&self, state: &mut H) {
466 let Punctuated { inner, last } = self;
467 inner.hash(state);
468 last.hash(state);
469 }
470}
471
472#[cfg(feature = "extra-traits")]
473#[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
474impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
476 let mut list = f.debug_list();
477 for (t, p) in &self.inner {
478 list.entry(t);
479 list.entry(p);
480 }
481 if let Some(last) = &self.last {
482 list.entry(last);
483 }
484 list.finish()
485 }
486}
487
488impl<T, P> FromIterator<T> for Punctuated<T, P>
489where
490 P: Default,
491{
492 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
493 let mut ret = Punctuated::new();
494 ret.extend(i);
495 ret
496 }
497}
498
499impl<T, P> Extend<T> for Punctuated<T, P>
500where
501 P: Default,
502{
503 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
504 for value in i {
505 self.push(value);
506 }
507 }
508}
509
510impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
511 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
512 let mut ret = Punctuated::new();
513 do_extend(&mut ret, i.into_iter());
514 ret
515 }
516}
517
518impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P>
519where
520 P: Default,
521{
522 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
523 if !self.empty_or_trailing() {
524 self.push_punct(P::default());
525 }
526 do_extend(self, i.into_iter());
527 }
528}
529
530fn do_extend<T, P, I>(punctuated: &mut Punctuated<T, P>, i: I)
531where
532 I: Iterator<Item = Pair<T, P>>,
533{
534 let mut nomore = false;
535 for pair in i {
536 if nomore {
537 panic!("punctuated extended with items after a Pair::End");
538 }
539 match pair {
540 Pair::Punctuated(a, b) => punctuated.inner.push((a, b)),
541 Pair::End(a) => {
542 punctuated.last = Some(Box::new(a));
543 nomore = true;
544 }
545 }
546 }
547}
548
549impl<T, P> IntoIterator for Punctuated<T, P> {
550 type Item = T;
551 type IntoIter = IntoIter<T>;
552
553 fn into_iter(self) -> Self::IntoIter {
554 let mut elements = Vec::with_capacity(self.len());
555
556 for (t, _) in self.inner {
557 elements.push(t);
558 }
559 if let Some(t) = self.last {
560 elements.push(*t);
561 }
562
563 IntoIter {
564 inner: elements.into_iter(),
565 }
566 }
567}
568
569impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
570 type Item = &'a T;
571 type IntoIter = Iter<'a, T>;
572
573 fn into_iter(self) -> Self::IntoIter {
574 Punctuated::iter(self)
575 }
576}
577
578impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
579 type Item = &'a mut T;
580 type IntoIter = IterMut<'a, T>;
581
582 fn into_iter(self) -> Self::IntoIter {
583 Punctuated::iter_mut(self)
584 }
585}
586
587impl<T, P> Default for Punctuated<T, P> {
588 fn default() -> Self {
589 Punctuated::new()
590 }
591}
592
593pub struct Pairs<'a, T: 'a, P: 'a> {
599 inner: slice::Iter<'a, (T, P)>,
600 last: option::IntoIter<&'a T>,
601}
602
603impl<'a, T, P> Iterator for Pairs<'a, T, P> {
604 type Item = Pair<&'a T, &'a P>;
605
606 fn next(&mut self) -> Option<Self::Item> {
607 self.inner
608 .next()
609 .map(|(t, p)| Pair::Punctuated(t, p))
610 .or_else(|| self.last.next().map(Pair::End))
611 }
612
613 fn size_hint(&self) -> (usize, Option<usize>) {
614 (self.len(), Some(self.len()))
615 }
616}
617
618impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
619 fn next_back(&mut self) -> Option<Self::Item> {
620 self.last
621 .next()
622 .map(Pair::End)
623 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
624 }
625}
626
627impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
628 fn len(&self) -> usize {
629 self.inner.len() + self.last.len()
630 }
631}
632
633impl<'a, T, P> Clone for Pairs<'a, T, P> {
635 fn clone(&self) -> Self {
636 Pairs {
637 inner: self.inner.clone(),
638 last: self.last.clone(),
639 }
640 }
641}
642
643pub struct PairsMut<'a, T: 'a, P: 'a> {
649 inner: slice::IterMut<'a, (T, P)>,
650 last: option::IntoIter<&'a mut T>,
651}
652
653impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
654 type Item = Pair<&'a mut T, &'a mut P>;
655
656 fn next(&mut self) -> Option<Self::Item> {
657 self.inner
658 .next()
659 .map(|(t, p)| Pair::Punctuated(t, p))
660 .or_else(|| self.last.next().map(Pair::End))
661 }
662
663 fn size_hint(&self) -> (usize, Option<usize>) {
664 (self.len(), Some(self.len()))
665 }
666}
667
668impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
669 fn next_back(&mut self) -> Option<Self::Item> {
670 self.last
671 .next()
672 .map(Pair::End)
673 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
674 }
675}
676
677impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
678 fn len(&self) -> usize {
679 self.inner.len() + self.last.len()
680 }
681}
682
683pub struct IntoPairs<T, P> {
689 inner: vec::IntoIter<(T, P)>,
690 last: option::IntoIter<T>,
691}
692
693impl<T, P> Iterator for IntoPairs<T, P> {
694 type Item = Pair<T, P>;
695
696 fn next(&mut self) -> Option<Self::Item> {
697 self.inner
698 .next()
699 .map(|(t, p)| Pair::Punctuated(t, p))
700 .or_else(|| self.last.next().map(Pair::End))
701 }
702
703 fn size_hint(&self) -> (usize, Option<usize>) {
704 (self.len(), Some(self.len()))
705 }
706}
707
708impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
709 fn next_back(&mut self) -> Option<Self::Item> {
710 self.last
711 .next()
712 .map(Pair::End)
713 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
714 }
715}
716
717impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
718 fn len(&self) -> usize {
719 self.inner.len() + self.last.len()
720 }
721}
722
723impl<T, P> Clone for IntoPairs<T, P>
724where
725 T: Clone,
726 P: Clone,
727{
728 fn clone(&self) -> Self {
729 IntoPairs {
730 inner: self.inner.clone(),
731 last: self.last.clone(),
732 }
733 }
734}
735
736pub struct IntoIter<T> {
742 inner: vec::IntoIter<T>,
743}
744
745impl<T> Iterator for IntoIter<T> {
746 type Item = T;
747
748 fn next(&mut self) -> Option<Self::Item> {
749 self.inner.next()
750 }
751
752 fn size_hint(&self) -> (usize, Option<usize>) {
753 (self.len(), Some(self.len()))
754 }
755}
756
757impl<T> DoubleEndedIterator for IntoIter<T> {
758 fn next_back(&mut self) -> Option<Self::Item> {
759 self.inner.next_back()
760 }
761}
762
763impl<T> ExactSizeIterator for IntoIter<T> {
764 fn len(&self) -> usize {
765 self.inner.len()
766 }
767}
768
769impl<T> Clone for IntoIter<T>
770where
771 T: Clone,
772{
773 fn clone(&self) -> Self {
774 IntoIter {
775 inner: self.inner.clone(),
776 }
777 }
778}
779
780pub struct Iter<'a, T: 'a> {
786 inner: Box<NoDrop<dyn IterTrait<'a, T> + 'a>>,
787}
788
789trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> + DoubleEndedIterator + ExactSizeIterator {
790 fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>>;
791}
792
793struct PrivateIter<'a, T: 'a, P: 'a> {
794 inner: slice::Iter<'a, (T, P)>,
795 last: option::IntoIter<&'a T>,
796}
797
798impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
799where
800 slice::Iter<'a, (T, P)>: TrivialDrop,
801 option::IntoIter<&'a T>: TrivialDrop,
802{
803}
804
805#[cfg(any(feature = "full", feature = "derive"))]
806pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
807 Iter {
808 inner: Box::new(NoDrop::new(iter::empty())),
809 }
810}
811
812impl<'a, T> Clone for Iter<'a, T> {
814 fn clone(&self) -> Self {
815 Iter {
816 inner: self.inner.clone_box(),
817 }
818 }
819}
820
821impl<'a, T> Iterator for Iter<'a, T> {
822 type Item = &'a T;
823
824 fn next(&mut self) -> Option<Self::Item> {
825 self.inner.next()
826 }
827
828 fn size_hint(&self) -> (usize, Option<usize>) {
829 (self.len(), Some(self.len()))
830 }
831}
832
833impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
834 fn next_back(&mut self) -> Option<Self::Item> {
835 self.inner.next_back()
836 }
837}
838
839impl<'a, T> ExactSizeIterator for Iter<'a, T> {
840 fn len(&self) -> usize {
841 self.inner.len()
842 }
843}
844
845impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
846 type Item = &'a T;
847
848 fn next(&mut self) -> Option<Self::Item> {
849 self.inner
850 .next()
851 .map(|pair| &pair.0)
852 .or_else(|| self.last.next())
853 }
854}
855
856impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
857 fn next_back(&mut self) -> Option<Self::Item> {
858 self.last
859 .next()
860 .or_else(|| self.inner.next_back().map(|pair| &pair.0))
861 }
862}
863
864impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
865 fn len(&self) -> usize {
866 self.inner.len() + self.last.len()
867 }
868}
869
870impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
872 fn clone(&self) -> Self {
873 PrivateIter {
874 inner: self.inner.clone(),
875 last: self.last.clone(),
876 }
877 }
878}
879
880impl<'a, T, I> IterTrait<'a, T> for I
881where
882 T: 'a,
883 I: DoubleEndedIterator<Item = &'a T>
884 + ExactSizeIterator<Item = &'a T>
885 + Clone
886 + TrivialDrop
887 + 'a,
888{
889 fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>> {
890 Box::new(NoDrop::new(self.clone()))
891 }
892}
893
894pub struct IterMut<'a, T: 'a> {
900 inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
901}
902
903trait IterMutTrait<'a, T: 'a>:
904 DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
905{
906}
907
908struct PrivateIterMut<'a, T: 'a, P: 'a> {
909 inner: slice::IterMut<'a, (T, P)>,
910 last: option::IntoIter<&'a mut T>,
911}
912
913impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
914where
915 slice::IterMut<'a, (T, P)>: TrivialDrop,
916 option::IntoIter<&'a mut T>: TrivialDrop,
917{
918}
919
920#[cfg(any(feature = "full", feature = "derive"))]
921pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
922 IterMut {
923 inner: Box::new(NoDrop::new(iter::empty())),
924 }
925}
926
927impl<'a, T> Iterator for IterMut<'a, T> {
928 type Item = &'a mut T;
929
930 fn next(&mut self) -> Option<Self::Item> {
931 self.inner.next()
932 }
933
934 fn size_hint(&self) -> (usize, Option<usize>) {
935 (self.len(), Some(self.len()))
936 }
937}
938
939impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
940 fn next_back(&mut self) -> Option<Self::Item> {
941 self.inner.next_back()
942 }
943}
944
945impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
946 fn len(&self) -> usize {
947 self.inner.len()
948 }
949}
950
951impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
952 type Item = &'a mut T;
953
954 fn next(&mut self) -> Option<Self::Item> {
955 self.inner
956 .next()
957 .map(|pair| &mut pair.0)
958 .or_else(|| self.last.next())
959 }
960}
961
962impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
963 fn next_back(&mut self) -> Option<Self::Item> {
964 self.last
965 .next()
966 .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
967 }
968}
969
970impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
971 fn len(&self) -> usize {
972 self.inner.len() + self.last.len()
973 }
974}
975
976impl<'a, T, I> IterMutTrait<'a, T> for I
977where
978 T: 'a,
979 I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T> + 'a,
980{
981}
982
983pub enum Pair<T, P> {
990 Punctuated(T, P),
991 End(T),
992}
993
994impl<T, P> Pair<T, P> {
995 pub fn into_value(self) -> T {
998 match self {
999 Pair::Punctuated(t, _) | Pair::End(t) => t,
1000 }
1001 }
1002
1003 pub fn value(&self) -> &T {
1005 match self {
1006 Pair::Punctuated(t, _) | Pair::End(t) => t,
1007 }
1008 }
1009
1010 pub fn value_mut(&mut self) -> &mut T {
1012 match self {
1013 Pair::Punctuated(t, _) | Pair::End(t) => t,
1014 }
1015 }
1016
1017 pub fn punct(&self) -> Option<&P> {
1020 match self {
1021 Pair::Punctuated(_, p) => Some(p),
1022 Pair::End(_) => None,
1023 }
1024 }
1025
1026 pub fn punct_mut(&mut self) -> Option<&mut P> {
1045 match self {
1046 Pair::Punctuated(_, p) => Some(p),
1047 Pair::End(_) => None,
1048 }
1049 }
1050
1051 pub fn new(t: T, p: Option<P>) -> Self {
1054 match p {
1055 Some(p) => Pair::Punctuated(t, p),
1056 None => Pair::End(t),
1057 }
1058 }
1059
1060 pub fn into_tuple(self) -> (T, Option<P>) {
1063 match self {
1064 Pair::Punctuated(t, p) => (t, Some(p)),
1065 Pair::End(t) => (t, None),
1066 }
1067 }
1068}
1069
1070#[cfg(feature = "clone-impls")]
1071#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1072impl<T, P> Pair<&T, &P> {
1073 pub fn cloned(self) -> Pair<T, P>
1074 where
1075 T: Clone,
1076 P: Clone,
1077 {
1078 match self {
1079 Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
1080 Pair::End(t) => Pair::End(t.clone()),
1081 }
1082 }
1083}
1084
1085#[cfg(feature = "clone-impls")]
1086#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1087impl<T, P> Clone for Pair<T, P>
1088where
1089 T: Clone,
1090 P: Clone,
1091{
1092 fn clone(&self) -> Self {
1093 match self {
1094 Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
1095 Pair::End(t) => Pair::End(t.clone()),
1096 }
1097 }
1098}
1099
1100#[cfg(feature = "clone-impls")]
1101#[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1102impl<T, P> Copy for Pair<T, P>
1103where
1104 T: Copy,
1105 P: Copy,
1106{
1107}
1108
1109impl<T, P> Index<usize> for Punctuated<T, P> {
1110 type Output = T;
1111
1112 fn index(&self, index: usize) -> &Self::Output {
1113 if index.checked_add(1) == Some(self.len()) {
1114 match &self.last {
1115 Some(t) => t,
1116 None => &self.inner[index].0,
1117 }
1118 } else {
1119 &self.inner[index].0
1120 }
1121 }
1122}
1123
1124impl<T, P> IndexMut<usize> for Punctuated<T, P> {
1125 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1126 if index.checked_add(1) == Some(self.len()) {
1127 match &mut self.last {
1128 Some(t) => t,
1129 None => &mut self.inner[index].0,
1130 }
1131 } else {
1132 &mut self.inner[index].0
1133 }
1134 }
1135}
1136
1137#[cfg(all(feature = "fold", any(feature = "full", feature = "derive")))]
1138pub(crate) fn fold<T, P, V, F>(
1139 punctuated: Punctuated<T, P>,
1140 fold: &mut V,
1141 mut f: F,
1142) -> Punctuated<T, P>
1143where
1144 V: ?Sized,
1145 F: FnMut(&mut V, T) -> T,
1146{
1147 let Punctuated { inner, last } = punctuated;
1148
1149 let mut inner = VecDeque::from(inner);
1152 for _ in 0..inner.len() {
1153 if let Some((t, p)) = inner.pop_front() {
1154 inner.push_back((f(fold, t), p));
1155 }
1156 }
1157
1158 Punctuated {
1159 inner: Vec::from(inner),
1160 last: match last {
1161 Some(t) => Some(Box::new(f(fold, *t))),
1162 None => None,
1163 },
1164 }
1165}
1166
1167#[cfg(feature = "printing")]
1168mod printing {
1169 use crate::punctuated::{Pair, Punctuated};
1170 use proc_macro2::TokenStream;
1171 use quote::{ToTokens, TokenStreamExt as _};
1172
1173 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1174 impl<T, P> ToTokens for Punctuated<T, P>
1175 where
1176 T: ToTokens,
1177 P: ToTokens,
1178 {
1179 fn to_tokens(&self, tokens: &mut TokenStream) {
1180 tokens.append_all(self.pairs());
1181 }
1182 }
1183
1184 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1185 impl<T, P> ToTokens for Pair<T, P>
1186 where
1187 T: ToTokens,
1188 P: ToTokens,
1189 {
1190 fn to_tokens(&self, tokens: &mut TokenStream) {
1191 match self {
1192 Pair::Punctuated(a, b) => {
1193 a.to_tokens(tokens);
1194 b.to_tokens(tokens);
1195 }
1196 Pair::End(a) => a.to_tokens(tokens),
1197 }
1198 }
1199 }
1200}