1#[cfg(feature = "extra-traits")]
24use std::fmt::{self, Debug};
25#[cfg(any(feature = "full", feature = "derive"))]
26use std::iter;
27use std::iter::FromIterator;
28use std::ops::{Index, IndexMut};
29use std::option;
30use std::slice;
31use std::vec;
32
33#[cfg(feature = "parsing")]
34use crate::parse::{Parse, ParseStream, Result};
35#[cfg(feature = "parsing")]
36use crate::token::Token;
37
38#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))]
45#[cfg_attr(feature = "clone-impls", derive(Clone))]
46pub struct Punctuated<T, P> {
47 inner: Vec<(T, P)>,
48 last: Option<Box<T>>,
49}
50
51impl<T, P> Punctuated<T, P> {
52 pub fn new() -> Punctuated<T, P> {
54 Punctuated {
55 inner: Vec::new(),
56 last: None,
57 }
58 }
59
60 pub fn is_empty(&self) -> bool {
63 self.inner.len() == 0 && self.last.is_none()
64 }
65
66 pub fn len(&self) -> usize {
71 self.inner.len() + if self.last.is_some() { 1 } else { 0 }
72 }
73
74 pub fn first(&self) -> Option<&T> {
76 self.iter().next()
77 }
78
79 pub fn last(&self) -> Option<&T> {
81 if self.last.is_some() {
82 self.last.as_ref().map(Box::as_ref)
83 } else {
84 self.inner.last().map(|pair| &pair.0)
85 }
86 }
87
88 pub fn last_mut(&mut self) -> Option<&mut T> {
90 if self.last.is_some() {
91 self.last.as_mut().map(Box::as_mut)
92 } else {
93 self.inner.last_mut().map(|pair| &mut pair.0)
94 }
95 }
96
97 pub fn iter(&self) -> Iter<T> {
99 Iter {
100 inner: Box::new(PrivateIter {
101 inner: self.inner.iter(),
102 last: self.last.as_ref().map(Box::as_ref).into_iter(),
103 }),
104 }
105 }
106
107 pub fn iter_mut(&mut self) -> IterMut<T> {
110 IterMut {
111 inner: Box::new(PrivateIterMut {
112 inner: self.inner.iter_mut(),
113 last: self.last.as_mut().map(Box::as_mut).into_iter(),
114 }),
115 }
116 }
117
118 pub fn pairs(&self) -> Pairs<T, P> {
121 Pairs {
122 inner: self.inner.iter(),
123 last: self.last.as_ref().map(Box::as_ref).into_iter(),
124 }
125 }
126
127 pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
130 PairsMut {
131 inner: self.inner.iter_mut(),
132 last: self.last.as_mut().map(Box::as_mut).into_iter(),
133 }
134 }
135
136 pub fn into_pairs(self) -> IntoPairs<T, P> {
139 IntoPairs {
140 inner: self.inner.into_iter(),
141 last: self.last.map(|t| *t).into_iter(),
142 }
143 }
144
145 pub fn push_value(&mut self, value: T) {
158 assert!(self.empty_or_trailing());
159 self.last = Some(Box::new(value));
160 }
161
162 pub fn push_punct(&mut self, punctuation: P) {
170 assert!(self.last.is_some());
171 let last = self.last.take().unwrap();
172 self.inner.push((*last, punctuation));
173 }
174
175 pub fn pop(&mut self) -> Option<Pair<T, P>> {
178 if self.last.is_some() {
179 self.last.take().map(|t| Pair::End(*t))
180 } else {
181 self.inner.pop().map(|(t, d)| Pair::Punctuated(t, d))
182 }
183 }
184
185 pub fn trailing_punct(&self) -> bool {
188 self.last.is_none() && !self.is_empty()
189 }
190
191 pub fn empty_or_trailing(&self) -> bool {
196 self.last.is_none()
197 }
198
199 pub fn push(&mut self, value: T)
205 where
206 P: Default,
207 {
208 if !self.empty_or_trailing() {
209 self.push_punct(Default::default());
210 }
211 self.push_value(value);
212 }
213
214 pub fn insert(&mut self, index: usize, value: T)
221 where
222 P: Default,
223 {
224 assert!(index <= self.len());
225
226 if index == self.len() {
227 self.push(value);
228 } else {
229 self.inner.insert(index, (value, Default::default()));
230 }
231 }
232
233 #[cfg(feature = "parsing")]
242 pub fn parse_terminated(input: ParseStream) -> Result<Self>
243 where
244 T: Parse,
245 P: Parse,
246 {
247 Self::parse_terminated_with(input, T::parse)
248 }
249
250 #[cfg(feature = "parsing")]
262 pub fn parse_terminated_with(
263 input: ParseStream,
264 parser: fn(ParseStream) -> Result<T>,
265 ) -> Result<Self>
266 where
267 P: Parse,
268 {
269 let mut punctuated = Punctuated::new();
270
271 loop {
272 if input.is_empty() {
273 break;
274 }
275 let value = parser(input)?;
276 punctuated.push_value(value);
277 if input.is_empty() {
278 break;
279 }
280 let punct = input.parse()?;
281 punctuated.push_punct(punct);
282 }
283
284 Ok(punctuated)
285 }
286
287 #[cfg(feature = "parsing")]
298 pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
299 where
300 T: Parse,
301 P: Token + Parse,
302 {
303 Self::parse_separated_nonempty_with(input, T::parse)
304 }
305
306 #[cfg(feature = "parsing")]
318 pub fn parse_separated_nonempty_with(
319 input: ParseStream,
320 parser: fn(ParseStream) -> Result<T>,
321 ) -> Result<Self>
322 where
323 P: Token + Parse,
324 {
325 let mut punctuated = Punctuated::new();
326
327 loop {
328 let value = parser(input)?;
329 punctuated.push_value(value);
330 if !P::peek(input.cursor()) {
331 break;
332 }
333 let punct = input.parse()?;
334 punctuated.push_punct(punct);
335 }
336
337 Ok(punctuated)
338 }
339}
340
341#[cfg(feature = "extra-traits")]
342impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
343 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
344 let mut list = f.debug_list();
345 for (t, p) in &self.inner {
346 list.entry(t);
347 list.entry(p);
348 }
349 if let Some(last) = &self.last {
350 list.entry(last);
351 }
352 list.finish()
353 }
354}
355
356impl<T, P> FromIterator<T> for Punctuated<T, P>
357where
358 P: Default,
359{
360 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
361 let mut ret = Punctuated::new();
362 ret.extend(i);
363 ret
364 }
365}
366
367impl<T, P> Extend<T> for Punctuated<T, P>
368where
369 P: Default,
370{
371 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
372 for value in i {
373 self.push(value);
374 }
375 }
376}
377
378impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
379 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
380 let mut ret = Punctuated::new();
381 ret.extend(i);
382 ret
383 }
384}
385
386impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
387 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
388 assert!(self.empty_or_trailing());
389 let mut nomore = false;
390 for pair in i {
391 if nomore {
392 panic!("Punctuated extended with items after a Pair::End");
393 }
394 match pair {
395 Pair::Punctuated(a, b) => self.inner.push((a, b)),
396 Pair::End(a) => {
397 self.last = Some(Box::new(a));
398 nomore = true;
399 }
400 }
401 }
402 }
403}
404
405impl<T, P> IntoIterator for Punctuated<T, P> {
406 type Item = T;
407 type IntoIter = IntoIter<T>;
408
409 fn into_iter(self) -> Self::IntoIter {
410 let mut elements = Vec::with_capacity(self.len());
411 elements.extend(self.inner.into_iter().map(|pair| pair.0));
412 elements.extend(self.last.map(|t| *t));
413
414 IntoIter {
415 inner: elements.into_iter(),
416 }
417 }
418}
419
420impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
421 type Item = &'a T;
422 type IntoIter = Iter<'a, T>;
423
424 fn into_iter(self) -> Self::IntoIter {
425 Punctuated::iter(self)
426 }
427}
428
429impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
430 type Item = &'a mut T;
431 type IntoIter = IterMut<'a, T>;
432
433 fn into_iter(self) -> Self::IntoIter {
434 Punctuated::iter_mut(self)
435 }
436}
437
438impl<T, P> Default for Punctuated<T, P> {
439 fn default() -> Self {
440 Punctuated::new()
441 }
442}
443
444pub struct Pairs<'a, T: 'a, P: 'a> {
450 inner: slice::Iter<'a, (T, P)>,
451 last: option::IntoIter<&'a T>,
452}
453
454impl<'a, T, P> Iterator for Pairs<'a, T, P> {
455 type Item = Pair<&'a T, &'a P>;
456
457 fn next(&mut self) -> Option<Self::Item> {
458 self.inner
459 .next()
460 .map(|(t, p)| Pair::Punctuated(t, p))
461 .or_else(|| self.last.next().map(Pair::End))
462 }
463
464 fn size_hint(&self) -> (usize, Option<usize>) {
465 (self.len(), Some(self.len()))
466 }
467}
468
469impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
470 fn next_back(&mut self) -> Option<Self::Item> {
471 self.last
472 .next()
473 .map(Pair::End)
474 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
475 }
476}
477
478impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
479 fn len(&self) -> usize {
480 self.inner.len() + self.last.len()
481 }
482}
483
484impl<'a, T, P> Clone for Pairs<'a, T, P> {
486 fn clone(&self) -> Self {
487 Pairs {
488 inner: self.inner.clone(),
489 last: self.last.clone(),
490 }
491 }
492}
493
494pub struct PairsMut<'a, T: 'a, P: 'a> {
500 inner: slice::IterMut<'a, (T, P)>,
501 last: option::IntoIter<&'a mut T>,
502}
503
504impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
505 type Item = Pair<&'a mut T, &'a mut P>;
506
507 fn next(&mut self) -> Option<Self::Item> {
508 self.inner
509 .next()
510 .map(|(t, p)| Pair::Punctuated(t, p))
511 .or_else(|| self.last.next().map(Pair::End))
512 }
513
514 fn size_hint(&self) -> (usize, Option<usize>) {
515 (self.len(), Some(self.len()))
516 }
517}
518
519impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
520 fn next_back(&mut self) -> Option<Self::Item> {
521 self.last
522 .next()
523 .map(Pair::End)
524 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
525 }
526}
527
528impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
529 fn len(&self) -> usize {
530 self.inner.len() + self.last.len()
531 }
532}
533
534#[derive(Clone)]
540pub struct IntoPairs<T, P> {
541 inner: vec::IntoIter<(T, P)>,
542 last: option::IntoIter<T>,
543}
544
545impl<T, P> Iterator for IntoPairs<T, P> {
546 type Item = Pair<T, P>;
547
548 fn next(&mut self) -> Option<Self::Item> {
549 self.inner
550 .next()
551 .map(|(t, p)| Pair::Punctuated(t, p))
552 .or_else(|| self.last.next().map(Pair::End))
553 }
554
555 fn size_hint(&self) -> (usize, Option<usize>) {
556 (self.len(), Some(self.len()))
557 }
558}
559
560impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
561 fn next_back(&mut self) -> Option<Self::Item> {
562 self.last
563 .next()
564 .map(Pair::End)
565 .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
566 }
567}
568
569impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
570 fn len(&self) -> usize {
571 self.inner.len() + self.last.len()
572 }
573}
574
575#[derive(Clone)]
581pub struct IntoIter<T> {
582 inner: vec::IntoIter<T>,
583}
584
585impl<T> Iterator for IntoIter<T> {
586 type Item = T;
587
588 fn next(&mut self) -> Option<Self::Item> {
589 self.inner.next()
590 }
591
592 fn size_hint(&self) -> (usize, Option<usize>) {
593 (self.len(), Some(self.len()))
594 }
595}
596
597impl<T> DoubleEndedIterator for IntoIter<T> {
598 fn next_back(&mut self) -> Option<Self::Item> {
599 self.inner.next_back()
600 }
601}
602
603impl<T> ExactSizeIterator for IntoIter<T> {
604 fn len(&self) -> usize {
605 self.inner.len()
606 }
607}
608
609pub struct Iter<'a, T: 'a> {
615 inner: Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>,
619}
620
621trait IterTrait<'a, T: 'a>:
622 DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T>
623{
624 fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a>;
625}
626
627struct PrivateIter<'a, T: 'a, P: 'a> {
628 inner: slice::Iter<'a, (T, P)>,
629 last: option::IntoIter<&'a T>,
630}
631
632#[cfg(any(feature = "full", feature = "derive"))]
633pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
634 Iter {
635 inner: Box::new(iter::empty()),
636 }
637}
638
639impl<'a, T> Clone for Iter<'a, T> {
641 fn clone(&self) -> Self {
642 Iter {
643 inner: self.inner.clone_box(),
644 }
645 }
646}
647
648impl<'a, T> Iterator for Iter<'a, T> {
649 type Item = &'a T;
650
651 fn next(&mut self) -> Option<Self::Item> {
652 self.inner.next()
653 }
654
655 fn size_hint(&self) -> (usize, Option<usize>) {
656 (self.len(), Some(self.len()))
657 }
658}
659
660impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
661 fn next_back(&mut self) -> Option<Self::Item> {
662 self.inner.next_back()
663 }
664}
665
666impl<'a, T> ExactSizeIterator for Iter<'a, T> {
667 fn len(&self) -> usize {
668 self.inner.len()
669 }
670}
671
672impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
673 type Item = &'a T;
674
675 fn next(&mut self) -> Option<Self::Item> {
676 self.inner
677 .next()
678 .map(|pair| &pair.0)
679 .or_else(|| self.last.next())
680 }
681}
682
683impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
684 fn next_back(&mut self) -> Option<Self::Item> {
685 self.last
686 .next()
687 .or_else(|| self.inner.next_back().map(|pair| &pair.0))
688 }
689}
690
691impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
692 fn len(&self) -> usize {
693 self.inner.len() + self.last.len()
694 }
695}
696
697impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
699 fn clone(&self) -> Self {
700 PrivateIter {
701 inner: self.inner.clone(),
702 last: self.last.clone(),
703 }
704 }
705}
706
707impl<'a, T: 'a, I: 'a> IterTrait<'a, T> for I
708where
709 I: DoubleEndedIterator<Item = &'a T> + ExactSizeIterator<Item = &'a T> + Clone,
710{
711 fn clone_box(&self) -> Box<dyn IterTrait<'a, T, Item = &'a T> + 'a> {
712 Box::new(self.clone())
713 }
714}
715
716pub struct IterMut<'a, T: 'a> {
722 inner: Box<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>,
723}
724
725trait IterMutTrait<'a, T: 'a>:
726 DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
727{
728}
729
730struct PrivateIterMut<'a, T: 'a, P: 'a> {
731 inner: slice::IterMut<'a, (T, P)>,
732 last: option::IntoIter<&'a mut T>,
733}
734
735#[cfg(any(feature = "full", feature = "derive"))]
736pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
737 IterMut {
738 inner: Box::new(iter::empty()),
739 }
740}
741
742impl<'a, T> Iterator for IterMut<'a, T> {
743 type Item = &'a mut T;
744
745 fn next(&mut self) -> Option<Self::Item> {
746 self.inner.next()
747 }
748
749 fn size_hint(&self) -> (usize, Option<usize>) {
750 (self.len(), Some(self.len()))
751 }
752}
753
754impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
755 fn next_back(&mut self) -> Option<Self::Item> {
756 self.inner.next_back()
757 }
758}
759
760impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
761 fn len(&self) -> usize {
762 self.inner.len()
763 }
764}
765
766impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
767 type Item = &'a mut T;
768
769 fn next(&mut self) -> Option<Self::Item> {
770 self.inner
771 .next()
772 .map(|pair| &mut pair.0)
773 .or_else(|| self.last.next())
774 }
775}
776
777impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
778 fn next_back(&mut self) -> Option<Self::Item> {
779 self.last
780 .next()
781 .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
782 }
783}
784
785impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
786 fn len(&self) -> usize {
787 self.inner.len() + self.last.len()
788 }
789}
790
791impl<'a, T: 'a, I: 'a> IterMutTrait<'a, T> for I where
792 I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
793{
794}
795
796#[cfg_attr(feature = "clone-impls", derive(Clone))]
803pub enum Pair<T, P> {
804 Punctuated(T, P),
805 End(T),
806}
807
808impl<T, P> Pair<T, P> {
809 pub fn into_value(self) -> T {
812 match self {
813 Pair::Punctuated(t, _) | Pair::End(t) => t,
814 }
815 }
816
817 pub fn value(&self) -> &T {
819 match self {
820 Pair::Punctuated(t, _) | Pair::End(t) => t,
821 }
822 }
823
824 pub fn value_mut(&mut self) -> &mut T {
826 match self {
827 Pair::Punctuated(t, _) | Pair::End(t) => t,
828 }
829 }
830
831 pub fn punct(&self) -> Option<&P> {
834 match self {
835 Pair::Punctuated(_, d) => Some(d),
836 Pair::End(_) => None,
837 }
838 }
839
840 pub fn new(t: T, d: Option<P>) -> Self {
843 match d {
844 Some(d) => Pair::Punctuated(t, d),
845 None => Pair::End(t),
846 }
847 }
848
849 pub fn into_tuple(self) -> (T, Option<P>) {
852 match self {
853 Pair::Punctuated(t, d) => (t, Some(d)),
854 Pair::End(t) => (t, None),
855 }
856 }
857}
858
859impl<T, P> Index<usize> for Punctuated<T, P> {
860 type Output = T;
861
862 fn index(&self, index: usize) -> &Self::Output {
863 if index == self.len() - 1 {
864 match &self.last {
865 Some(t) => t,
866 None => &self.inner[index].0,
867 }
868 } else {
869 &self.inner[index].0
870 }
871 }
872}
873
874impl<T, P> IndexMut<usize> for Punctuated<T, P> {
875 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
876 if index == self.len() - 1 {
877 match &mut self.last {
878 Some(t) => t,
879 None => &mut self.inner[index].0,
880 }
881 } else {
882 &mut self.inner[index].0
883 }
884 }
885}
886
887#[cfg(feature = "printing")]
888mod printing {
889 use super::*;
890 use proc_macro2::TokenStream;
891 use quote::{ToTokens, TokenStreamExt};
892
893 impl<T, P> ToTokens for Punctuated<T, P>
894 where
895 T: ToTokens,
896 P: ToTokens,
897 {
898 fn to_tokens(&self, tokens: &mut TokenStream) {
899 tokens.append_all(self.pairs())
900 }
901 }
902
903 impl<T, P> ToTokens for Pair<T, P>
904 where
905 T: ToTokens,
906 P: ToTokens,
907 {
908 fn to_tokens(&self, tokens: &mut TokenStream) {
909 match self {
910 Pair::Punctuated(a, b) => {
911 a.to_tokens(tokens);
912 b.to_tokens(tokens);
913 }
914 Pair::End(a) => a.to_tokens(tokens),
915 }
916 }
917 }
918}