css_parse/traits/
parse.rs1use crate::{Build, Parser, Peek, Result, diagnostics};
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 T
29where
30 T: Peek<'a> + Build<'a>,
31{
32 fn parse(p: &mut Parser<'a>) -> Result<Self> {
33 if p.peek::<Self>() {
34 let c = p.next();
35 Ok(Self::build(p, c))
36 } else {
37 Err(diagnostics::Unexpected(p.next()))?
38 }
39 }
40}
41
42impl<'a, T> Parse<'a> for Option<T>
43where
44 T: Peek<'a> + Parse<'a>,
45{
46 fn parse(p: &mut Parser<'a>) -> Result<Self> {
47 p.parse_if_peek::<T>()
48 }
49}
50
51impl<'a, T> Parse<'a> for Vec<'a, T>
52where
53 T: Peek<'a> + Parse<'a>,
54{
55 fn parse(p: &mut Parser<'a>) -> Result<Self> {
56 let mut vec = Vec::new_in(p.bump());
57 while let Some(item) = p.parse_if_peek::<T>()? {
58 vec.push(item);
59 }
60 Ok(vec)
61 }
62}
63
64macro_rules! impl_tuple {
65 ($($T:ident),*) => {
66 impl<'a, $($T),*> Parse<'a> for ($($T),*)
67 where
68 $($T: Parse<'a>),*
69 {
70 #[allow(non_snake_case)]
71 #[allow(unused)]
72 fn parse(p: &mut Parser<'a>) -> Result<Self> {
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);