use crate::parser::{
ast::{
expression::{Expression, ExpressionParsingError},
AstGeneratorContext, AstNode,
},
fragment::Fragment,
lexer::token::TokenTy,
};
#[derive(Debug)]
pub struct ParensExpression<'src> {
pub fragment: Fragment<'src>,
pub expression: Box<Expression<'src>>,
}
#[derive(Debug, Clone)]
pub enum ParensParsingError<'src> {
ClosingParenNotFound {
at: Fragment<'src>,
},
ErrorInParentheses(Box<ExpressionParsingError<'src>>),
ExpectedParensExpression {
at: Fragment<'src>,
},
}
#[rustfmt::skip] impl<'src> AstNode<'src> for ParensExpression<'src> {
type Error = ParensParsingError<'src>;
fn fragment(&self) -> Fragment<'src> {
self.fragment
}
fn try_parse(ctx: &mut AstGeneratorContext<'src>) -> Result<Self, Self::Error>
where
Self: Sized
{
let mut fork: AstGeneratorContext = ctx.fork();
fork
.next_if_is(TokenTy::LeftParen)
.ok_or_else( || ParensParsingError::ExpectedParensExpression { at: fork.peek_fragment() })?;
let expr: Expression = Expression::try_parse(&mut fork)
.map_err(Box::new)
.map_err(ParensParsingError::ErrorInParentheses)?;
fork
.next_if_is(TokenTy::RightParen)
.ok_or_else(|| ParensParsingError::ClosingParenNotFound { at: fork.peek_fragment() })?;
let consumed_source: Fragment = ctx.update(&fork).trimmed();
Ok(Self { fragment: consumed_source, expression: Box::new(expr) })
}
}