Skip to main content

moxy_token/parser/
mod.rs

1mod error;
2mod stream;
3
4#[doc(inline)]
5pub use error::*;
6
7#[doc(inline)]
8pub use stream::*;
9
10/// Parse a source string into a typed AST node, returning `Result<T, ParseError>`.
11///
12/// The type can be given explicitly with `as T` or inferred from context.
13///
14/// # Example
15/// ```
16/// use moxy_token::*;
17///
18/// let token: Fn = parse!("fn").unwrap();
19/// let token = parse!("fn" as Fn).unwrap();
20/// ```
21#[macro_export]
22macro_rules! parse {
23    ($src:tt as $ty:ty) => {{
24        use ::std::str::FromStr;
25        $crate::TokenStream::from_str(&$src.to_string())
26            .map_err($crate::parser::ParseError::from)
27            .and_then(|ts| ts.parse().parse::<$ty>())
28    }};
29    ($src:tt) => {{
30        use ::std::str::FromStr;
31        $crate::TokenStream::from_str(&$src.to_string())
32            .map_err($crate::parser::ParseError::from)
33            .and_then(|ts| ts.parse().parse())
34    }};
35}
36
37pub trait Parse: Sized {
38    fn parse(stream: &mut ParseStream) -> Result<Self, ParseError>;
39}
40
41pub trait Peek: Sized {
42    fn peek(stream: &mut ParseStream) -> bool;
43}
44
45impl<T: Parse> Peek for T {
46    fn peek(stream: &mut ParseStream) -> bool {
47        Self::parse(stream).is_ok()
48    }
49}
50
51impl<T: Parse> Parse for Option<T> {
52    #[inline]
53    fn parse(stream: &mut ParseStream) -> Result<Self, ParseError> {
54        if stream.peek::<T>() {
55            stream.parse().map(Some)
56        } else {
57            Ok(None)
58        }
59    }
60}
61
62impl<T: Parse> Parse for Vec<T> {
63    fn parse(stream: &mut ParseStream) -> Result<Self, ParseError> {
64        Ok(stream.parse_while::<T>())
65    }
66}
67
68impl<T: Parse> Parse for Box<T> {
69    fn parse(stream: &mut ParseStream) -> Result<Self, ParseError> {
70        Ok(Self::new(stream.parse()?))
71    }
72}