synkit_core/traits/
parse.rs

1use super::peek::Peek;
2use super::stream::TokenStream;
3
4/// Trait for types that can be parsed from a token stream.
5///
6/// This is the primary trait for defining how AST nodes are constructed
7/// from tokens. Implementations consume tokens from the stream and
8/// return either a parsed value or an error.
9///
10/// # Associated Types
11///
12/// - `Token`: The token type this parser consumes (e.g., `MyTok`)
13/// - `Error`: The error type for parse failures (e.g., `MyParseError`)
14///
15/// # Implementation Guidelines
16///
17/// 1. Use `stream.peek::<T>()` to check token types without consuming
18/// 2. Use `stream.parse::<T>()` to recursively parse nested structures
19/// 3. Use `stream.fork()` for backtracking lookahead
20/// 4. Return errors early with `?` operator
21///
22/// # Example
23///
24/// ```ignore
25/// use synkit::{Parse, Peek, TokenStream};
26///
27/// struct BinaryExpr {
28///     left: Box<Expr>,
29///     op: Operator,
30///     right: Box<Expr>,
31/// }
32///
33/// impl Parse for BinaryExpr {
34///     type Token = MyTok;
35///     type Error = ParseError;
36///
37///     fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
38///     where
39///         S: TokenStream<Token = Self::Token>,
40///     {
41///         let left = stream.parse()?;
42///         let op = stream.parse()?;
43///         let right = stream.parse()?;
44///         Ok(BinaryExpr { left, op, right })
45///     }
46/// }
47/// ```
48///
49/// # Blanket Implementations
50///
51/// - `Option<T>`: Parses `Some(T)` if `T::peek()` succeeds, else `None`
52/// - `Box<T>`: Delegates to `T::parse()` and boxes the result
53pub trait Parse: Sized {
54    /// The token type consumed by this parser.
55    type Token: Clone;
56    /// The error type for parse failures.
57    type Error;
58
59    /// Parse a value from the token stream.
60    ///
61    /// # Arguments
62    ///
63    /// * `stream` - The token stream to parse from
64    ///
65    /// # Returns
66    ///
67    /// * `Ok(Self)` - Successfully parsed value
68    /// * `Err(Self::Error)` - Parse failure with error details
69    fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
70    where
71        S: TokenStream<Token = Self::Token>;
72}
73
74impl<T> Parse for Option<T>
75where
76    T: Parse + Peek<Token = <T as Parse>::Token>,
77{
78    type Token = <T as Parse>::Token;
79    type Error = T::Error;
80
81    fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
82    where
83        S: TokenStream<Token = Self::Token>,
84    {
85        if stream.peek::<T>() {
86            Ok(Some(T::parse(stream)?))
87        } else {
88            Ok(None)
89        }
90    }
91}
92
93impl<T: Parse> Parse for Box<T> {
94    type Token = T::Token;
95    type Error = T::Error;
96
97    fn parse<S>(stream: &mut S) -> Result<Self, Self::Error>
98    where
99        S: TokenStream<Token = Self::Token>,
100    {
101        Ok(Box::new(T::parse(stream)?))
102    }
103}