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