1use crate::{Cursor, Parser, Peek, Result};
2use bumpalo::collections::Vec;
3
4pub trait Parse<'a>: Sized {
20 fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
21 where
22 I: Iterator<Item = Cursor> + Clone;
23
24 fn try_parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
25 where
26 I: Iterator<Item = Cursor> + Clone,
27 {
28 let checkpoint = p.checkpoint();
29 Self::parse(p).inspect_err(|_| p.rewind(checkpoint))
30 }
31}
32
33impl<'a, T> Parse<'a> for Option<T>
34where
35 T: Peek<'a> + Parse<'a>,
36{
37 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
38 where
39 Iter: Iterator<Item = Cursor> + Clone,
40 {
41 p.parse_if_peek::<T>()
42 }
43}
44
45impl<'a, T> Parse<'a> for Vec<'a, T>
46where
47 T: Peek<'a> + Parse<'a>,
48{
49 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
50 where
51 Iter: Iterator<Item = Cursor> + Clone,
52 {
53 let mut vec = Vec::new_in(p.bump());
54 while let Some(item) = p.parse_if_peek::<T>()? {
55 vec.push(item);
56 }
57 Ok(vec)
58 }
59}
60
61macro_rules! impl_tuple {
62 ($($T:ident),*) => {
63 impl<'a, $($T),*> Parse<'a> for ($($T),*)
64 where
65 $($T: Parse<'a>),*
66 {
67 #[allow(non_snake_case)]
68 #[allow(unused)]
69 fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
70 where
71 Iter: Iterator<Item = Cursor> + Clone,
72 {
73 $(let $T = p.parse::<$T>()?;)*
74 Ok(($($T),*))
75 }
76 }
77 };
78}
79
80impl_tuple!(A, B);
81impl_tuple!(A, B, C);
82impl_tuple!(A, B, C, D);
83impl_tuple!(A, B, C, D, E);
84impl_tuple!(A, B, C, D, E, F);
85impl_tuple!(A, B, C, D, E, F, G);
86impl_tuple!(A, B, C, D, E, F, G, H);
87impl_tuple!(A, B, C, D, E, F, G, H, I);
88impl_tuple!(A, B, C, D, E, F, G, H, I, J);
89impl_tuple!(A, B, C, D, E, F, G, H, I, J, K);
90impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);