Skip to main content

css_parse/traits/
parse.rs

1use crate::{Cursor, Parser, Peek, Result, Vec};
2
3/// This trait allows AST nodes to construct themselves from a mutable [Parser] instance.
4///
5/// Nodes that implement this trait are entitled to consume any number of [Cursors][crate::Cursor] from [Parser] in
6/// order to construct themselves. They may also consume some amount of tokens and still return an [Err] - there is no
7/// need to try and reset the [Parser] state on failure ([Parser::try_parse()] exists for this reason).
8///
9/// When wanting to parse child nodes, implementations should _not_ call [Parse::parse()] directly. Instead - call
10/// [`Parser::parse<T>()`]. Other convenience methods such as [`Parser::parse_if_peek<T>()`] and [`Parser::try_parse<T>()`]
11/// exist.
12///
13/// Any node implementing [Parse::parse()] gets [Parse::try_parse()] for free. It's unlikely that nodes can come up with
14/// a more efficient algorithm than the provided one, so it is not worth re-implementing [Parse::try_parse()].
15///
16/// If a Node can construct itself from a single [Cursor][crate::Cursor] it should implement
17/// [Peek][crate::Peek] and [Parse], where [Parse::parse()] calls [Parser::next()] and constructs from the cursor.
18pub trait Parse<'a>: Sized {
19	fn parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
20	where
21		I: Iterator<Item = Cursor> + Clone;
22
23	fn try_parse<I>(p: &mut Parser<'a, I>) -> Result<Self>
24	where
25		I: Iterator<Item = Cursor> + Clone,
26	{
27		let checkpoint = p.checkpoint();
28		Self::parse(p).inspect_err(|_| p.rewind(checkpoint))
29	}
30}
31
32impl<'a, T> Parse<'a> for Option<T>
33where
34	T: Peek<'a> + Parse<'a>,
35{
36	fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
37	where
38		Iter: Iterator<Item = Cursor> + Clone,
39	{
40		p.parse_if_peek::<T>()
41	}
42}
43
44impl<'a, T> Parse<'a> for Vec<'a, T>
45where
46	T: Peek<'a> + Parse<'a>,
47{
48	fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
49	where
50		Iter: Iterator<Item = Cursor> + Clone,
51	{
52		let mut vec = Vec::new_in(p.alloc());
53		while let Some(item) = p.parse_if_peek::<T>()? {
54			vec.push(item);
55		}
56		Ok(vec)
57	}
58}
59
60macro_rules! impl_tuple {
61    ($($T:ident),*) => {
62        impl<'a, $($T),*> Parse<'a> for ($($T),*)
63        where
64            $($T: Parse<'a>),*
65        {
66            #[allow(non_snake_case)]
67            #[allow(unused)]
68            fn parse<Iter>(p: &mut Parser<'a, Iter>) -> Result<Self>
69            where
70                Iter: Iterator<Item = Cursor> + Clone,
71            {
72                $(let $T = p.parse::<$T>()?;)*
73                Ok(($($T),*))
74            }
75        }
76    };
77}
78
79impl_tuple!(A, B);
80impl_tuple!(A, B, C);
81impl_tuple!(A, B, C, D);
82impl_tuple!(A, B, C, D, E);
83impl_tuple!(A, B, C, D, E, F);
84impl_tuple!(A, B, C, D, E, F, G);
85impl_tuple!(A, B, C, D, E, F, G, H);
86impl_tuple!(A, B, C, D, E, F, G, H, I);
87impl_tuple!(A, B, C, D, E, F, G, H, I, J);
88impl_tuple!(A, B, C, D, E, F, G, H, I, J, K);
89impl_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);