1use std::iter::FromIterator;
31use std::ops::{Index, IndexMut};
32use std::slice;
33use std::vec;
34#[cfg(feature = "extra-traits")]
35use std::fmt::{self, Debug};
36
37#[cfg(feature = "parsing")]
38use synom::{Synom, PResult};
39#[cfg(feature = "parsing")]
40use buffer::Cursor;
41#[cfg(feature = "parsing")]
42use parse_error;
43
44#[cfg_attr(feature = "extra-traits", derive(Eq, PartialEq, Hash))]
51#[cfg_attr(feature = "clone-impls", derive(Clone))]
52pub struct Punctuated<T, P> {
53 inner: Vec<(T, Option<P>)>,
54}
55
56impl<T, P> Punctuated<T, P> {
57 pub fn new() -> Punctuated<T, P> {
59 Punctuated { inner: Vec::new() }
60 }
61
62 pub fn is_empty(&self) -> bool {
65 self.inner.len() == 0
66 }
67
68 pub fn len(&self) -> usize {
73 self.inner.len()
74 }
75
76 pub fn first(&self) -> Option<Pair<&T, &P>> {
78 self.inner.first().map(|&(ref t, ref d)| match *d {
79 Some(ref d) => Pair::Punctuated(t, d),
80 None => Pair::End(t),
81 })
82 }
83
84 pub fn last(&self) -> Option<Pair<&T, &P>> {
86 self.inner.last().map(|&(ref t, ref d)| match *d {
87 Some(ref d) => Pair::Punctuated(t, d),
88 None => Pair::End(t),
89 })
90 }
91
92 pub fn last_mut(&mut self) -> Option<Pair<&mut T, &mut P>> {
94 self.inner
95 .last_mut()
96 .map(|&mut (ref mut t, ref mut d)| match *d {
97 Some(ref mut d) => Pair::Punctuated(t, d),
98 None => Pair::End(t),
99 })
100 }
101
102 pub fn iter(&self) -> Iter<T, P> {
104 Iter {
105 inner: self.inner.iter(),
106 }
107 }
108
109 pub fn iter_mut(&mut self) -> IterMut<T, P> {
112 IterMut {
113 inner: self.inner.iter_mut(),
114 }
115 }
116
117 pub fn pairs(&self) -> Pairs<T, P> {
120 Pairs {
121 inner: self.inner.iter(),
122 }
123 }
124
125 pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
128 PairsMut {
129 inner: self.inner.iter_mut(),
130 }
131 }
132
133 pub fn into_pairs(self) -> IntoPairs<T, P> {
136 IntoPairs {
137 inner: self.inner.into_iter(),
138 }
139 }
140
141 pub fn push_value(&mut self, value: T) {
154 assert!(self.empty_or_trailing());
155 self.inner.push((value, None));
156 }
157
158 pub fn push_punct(&mut self, punctuation: P) {
166 assert!(!self.is_empty());
167 let last = self.inner.last_mut().unwrap();
168 assert!(last.1.is_none());
169 last.1 = Some(punctuation);
170 }
171
172 pub fn pop(&mut self) -> Option<Pair<T, P>> {
175 self.inner.pop().map(|(t, d)| Pair::new(t, d))
176 }
177
178 pub fn trailing_punct(&self) -> bool {
181 self.inner
182 .last()
183 .map(|last| last.1.is_some())
184 .unwrap_or(false)
185 }
186
187 pub fn empty_or_trailing(&self) -> bool {
192 self.inner
193 .last()
194 .map(|last| last.1.is_some())
195 .unwrap_or(true)
196 }
197}
198
199impl<T, P> Punctuated<T, P>
200where
201 P: Default,
202{
203 pub fn push(&mut self, value: T) {
209 if !self.empty_or_trailing() {
210 self.push_punct(Default::default());
211 }
212 self.push_value(value);
213 }
214
215 pub fn insert(&mut self, index: usize, value: T) {
222 assert!(index <= self.len());
223
224 if index == self.len() {
225 self.push(value);
226 } else {
227 self.inner.insert(index, (value, Some(Default::default())));
228 }
229 }
230}
231
232#[cfg(feature = "extra-traits")]
233impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
234 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235 self.inner.fmt(f)
236 }
237}
238
239impl<T, P> FromIterator<T> for Punctuated<T, P>
240where
241 P: Default,
242{
243 fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
244 let mut ret = Punctuated::new();
245 ret.extend(i);
246 ret
247 }
248}
249
250impl<T, P> Extend<T> for Punctuated<T, P>
251where
252 P: Default,
253{
254 fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
255 for value in i {
256 self.push(value);
257 }
258 }
259}
260
261impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
262 fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
263 let mut ret = Punctuated::new();
264 ret.extend(i);
265 ret
266 }
267}
268
269impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P> {
270 fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
271 for pair in i {
272 match pair {
273 Pair::Punctuated(a, b) => self.inner.push((a, Some(b))),
274 Pair::End(a) => self.inner.push((a, None)),
275 }
276 }
277 }
278}
279
280impl<T, P> IntoIterator for Punctuated<T, P> {
281 type Item = T;
282 type IntoIter = IntoIter<T, P>;
283
284 fn into_iter(self) -> Self::IntoIter {
285 IntoIter {
286 inner: self.inner.into_iter(),
287 }
288 }
289}
290
291impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
292 type Item = &'a T;
293 type IntoIter = Iter<'a, T, P>;
294
295 fn into_iter(self) -> Self::IntoIter {
296 Punctuated::iter(self)
297 }
298}
299
300impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
301 type Item = &'a mut T;
302 type IntoIter = IterMut<'a, T, P>;
303
304 fn into_iter(self) -> Self::IntoIter {
305 Punctuated::iter_mut(self)
306 }
307}
308
309impl<T, P> Default for Punctuated<T, P> {
310 fn default() -> Self {
311 Punctuated::new()
312 }
313}
314
315pub struct Pairs<'a, T: 'a, P: 'a> {
321 inner: slice::Iter<'a, (T, Option<P>)>,
322}
323
324impl<'a, T, P> Iterator for Pairs<'a, T, P> {
325 type Item = Pair<&'a T, &'a P>;
326
327 fn next(&mut self) -> Option<Self::Item> {
328 self.inner.next().map(|pair| match pair.1 {
329 Some(ref p) => Pair::Punctuated(&pair.0, p),
330 None => Pair::End(&pair.0),
331 })
332 }
333}
334
335pub struct PairsMut<'a, T: 'a, P: 'a> {
341 inner: slice::IterMut<'a, (T, Option<P>)>,
342}
343
344impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
345 type Item = Pair<&'a mut T, &'a mut P>;
346
347 fn next(&mut self) -> Option<Self::Item> {
348 self.inner.next().map(|pair| match pair.1 {
349 Some(ref mut p) => Pair::Punctuated(&mut pair.0, p),
350 None => Pair::End(&mut pair.0),
351 })
352 }
353}
354
355pub struct IntoPairs<T, P> {
361 inner: vec::IntoIter<(T, Option<P>)>,
362}
363
364impl<T, P> Iterator for IntoPairs<T, P> {
365 type Item = Pair<T, P>;
366
367 fn next(&mut self) -> Option<Self::Item> {
368 self.inner.next().map(|pair| match pair.1 {
369 Some(p) => Pair::Punctuated(pair.0, p),
370 None => Pair::End(pair.0),
371 })
372 }
373}
374
375pub struct IntoIter<T, P> {
381 inner: vec::IntoIter<(T, Option<P>)>,
382}
383
384impl<T, P> Iterator for IntoIter<T, P> {
385 type Item = T;
386
387 fn next(&mut self) -> Option<Self::Item> {
388 self.inner.next().map(|pair| pair.0)
389 }
390}
391
392pub struct Iter<'a, T: 'a, P: 'a> {
398 inner: slice::Iter<'a, (T, Option<P>)>,
399}
400
401#[cfg(any(feature = "full", feature = "derive"))]
402impl<'a, T, P> Iter<'a, T, P> {
403 #[doc(hidden)]
405 pub fn private_empty() -> Self {
406 Iter {
407 inner: [].iter(),
408 }
409 }
410}
411
412impl<'a, T, P> Iterator for Iter<'a, T, P> {
413 type Item = &'a T;
414
415 fn next(&mut self) -> Option<Self::Item> {
416 self.inner.next().map(|pair| &pair.0)
417 }
418}
419
420pub struct IterMut<'a, T: 'a, P: 'a> {
426 inner: slice::IterMut<'a, (T, Option<P>)>,
427}
428
429impl<'a, T, P> Iterator for IterMut<'a, T, P> {
430 type Item = &'a mut T;
431
432 fn next(&mut self) -> Option<Self::Item> {
433 self.inner.next().map(|pair| &mut pair.0)
434 }
435}
436
437pub enum Pair<T, P> {
444 Punctuated(T, P),
445 End(T),
446}
447
448impl<T, P> Pair<T, P> {
449 pub fn into_value(self) -> T {
452 match self {
453 Pair::Punctuated(t, _) | Pair::End(t) => t,
454 }
455 }
456
457 pub fn value(&self) -> &T {
459 match *self {
460 Pair::Punctuated(ref t, _) | Pair::End(ref t) => t,
461 }
462 }
463
464 pub fn value_mut(&mut self) -> &mut T {
466 match *self {
467 Pair::Punctuated(ref mut t, _) | Pair::End(ref mut t) => t,
468 }
469 }
470
471 pub fn punct(&self) -> Option<&P> {
474 match *self {
475 Pair::Punctuated(_, ref d) => Some(d),
476 Pair::End(_) => None,
477 }
478 }
479
480 pub fn new(t: T, d: Option<P>) -> Self {
483 match d {
484 Some(d) => Pair::Punctuated(t, d),
485 None => Pair::End(t),
486 }
487 }
488
489 pub fn into_tuple(self) -> (T, Option<P>) {
492 match self {
493 Pair::Punctuated(t, d) => (t, Some(d)),
494 Pair::End(t) => (t, None),
495 }
496 }
497}
498
499impl<T, P> Index<usize> for Punctuated<T, P> {
500 type Output = T;
501
502 fn index(&self, index: usize) -> &Self::Output {
503 &self.inner[index].0
504 }
505}
506
507impl<T, P> IndexMut<usize> for Punctuated<T, P> {
508 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
509 &mut self.inner[index].0
510 }
511}
512
513#[cfg(feature = "parsing")]
514impl<T, P> Punctuated<T, P>
515where
516 T: Synom,
517 P: Synom,
518{
519 pub fn parse_separated(input: Cursor) -> PResult<Self> {
522 Self::parse_separated_with(input, T::parse)
523 }
524
525 pub fn parse_separated_nonempty(input: Cursor) -> PResult<Self> {
529 Self::parse_separated_nonempty_with(input, T::parse)
530 }
531
532 pub fn parse_terminated(input: Cursor) -> PResult<Self> {
535 Self::parse_terminated_with(input, T::parse)
536 }
537
538 pub fn parse_terminated_nonempty(input: Cursor) -> PResult<Self> {
541 Self::parse_terminated_nonempty_with(input, T::parse)
542 }
543}
544
545#[cfg(feature = "parsing")]
546impl<T, P> Punctuated<T, P>
547where
548 P: Synom,
549{
550 pub fn parse_separated_with(
553 input: Cursor,
554 parse: fn(Cursor) -> PResult<T>,
555 ) -> PResult<Self> {
556 Self::parse(input, parse, false)
557 }
558
559 pub fn parse_separated_nonempty_with(
562 input: Cursor,
563 parse: fn(Cursor) -> PResult<T>,
564 ) -> PResult<Self> {
565 match Self::parse(input, parse, false) {
566 Ok((ref b, _)) if b.is_empty() => parse_error(),
567 other => other,
568 }
569 }
570
571 pub fn parse_terminated_with(
574 input: Cursor,
575 parse: fn(Cursor) -> PResult<T>,
576 ) -> PResult<Self> {
577 Self::parse(input, parse, true)
578 }
579
580 pub fn parse_terminated_nonempty_with(
583 input: Cursor,
584 parse: fn(Cursor) -> PResult<T>,
585 ) -> PResult<Self> {
586 match Self::parse(input, parse, true) {
587 Ok((ref b, _)) if b.is_empty() => parse_error(),
588 other => other,
589 }
590 }
591
592 fn parse(
593 mut input: Cursor,
594 parse: fn(Cursor) -> PResult<T>,
595 terminated: bool,
596 ) -> PResult<Self> {
597 let mut res = Punctuated::new();
598
599 match parse(input) {
601 Err(_) => Ok((res, input)),
602 Ok((o, i)) => {
603 if i == input {
604 return parse_error();
605 }
606 input = i;
607 res.push_value(o);
608
609 while let Ok((s, i2)) = P::parse(input) {
611 if i2 == input {
612 break;
613 }
614
615 if let Ok((o3, i3)) = parse(i2) {
617 if i3 == i2 {
618 break;
619 }
620 res.push_punct(s);
621 res.push_value(o3);
622 input = i3;
623 } else {
624 break;
625 }
626 }
627 if terminated {
628 if let Ok((sep, after)) = P::parse(input) {
629 res.push_punct(sep);
630 input = after;
631 }
632 }
633 Ok((res, input))
634 }
635 }
636 }
637}
638
639#[cfg(feature = "printing")]
640mod printing {
641 use super::*;
642 use quote::{ToTokens, Tokens};
643
644 impl<T, P> ToTokens for Punctuated<T, P>
645 where
646 T: ToTokens,
647 P: ToTokens,
648 {
649 fn to_tokens(&self, tokens: &mut Tokens) {
650 tokens.append_all(self.pairs())
651 }
652 }
653
654 impl<T, P> ToTokens for Pair<T, P>
655 where
656 T: ToTokens,
657 P: ToTokens,
658 {
659 fn to_tokens(&self, tokens: &mut Tokens) {
660 match *self {
661 Pair::Punctuated(ref a, ref b) => {
662 a.to_tokens(tokens);
663 b.to_tokens(tokens);
664 }
665 Pair::End(ref a) => a.to_tokens(tokens),
666 }
667 }
668 }
669}