use crate::error::{ParserError, TemplateRenderError}; use crate::lexer::Token; use std::iter::Peekable; use std::slice::Iter; #[derive(Debug, PartialOrd, PartialEq)] pub(crate) enum Node<'a> { Text(&'a str), Expression(&'a str), } #[derive(Debug, PartialOrd, PartialEq)] enum ParserState { Text, Expression, } pub(crate) struct Parser<'source, 'tokens> { cursor: Peekable>>, state: ParserState, nodes: Vec>, } impl<'source, 'tokens, T> From for Parser<'source, 'tokens> where T: Into<&'tokens [Token<'source>]>, { fn from(value: T) -> Self { let tokens = value.into(); let cursor = tokens.iter().peekable(); Self { cursor, nodes: Default::default(), state: ParserState::Text, } } } impl<'source, 'tokens> Parser<'source, 'tokens> { pub(crate) fn collect(mut self) -> Result>, TemplateRenderError> { while let Some(token) = self.cursor.next() { match token { Token::Text(text) => self.text(text), Token::OpenBracket => self.open_bracket()?, Token::CloseBracket => self.close_bracket()?, } } Ok(self.nodes) } fn text(&mut self, data: &'source str) { match self.state { ParserState::Text => self.nodes.push(Node::Text(data)), ParserState::Expression => self.nodes.push(Node::Expression(data)), } } fn open_bracket(&mut self) -> Result<(), ParserError> { if self.state == ParserState::Expression { return Err(ParserError::OpenBracket); } self.state = ParserState::Expression; Ok(()) } fn close_bracket(&mut self) -> Result<(), ParserError> { if self.state != ParserState::Expression { return Err(ParserError::CloseBracket); } self.state = ParserState::Text; Ok(()) } }