mirror of
https://github.com/gorules/zen.git
synced 2026-10-05 16:02:40 +00:00
* feat: custom node * add zen template, expose $nodes and $root * add custom handler to go and nodejs * add support for python, improve bindings, add error to zen template * fix: correct binding exports for nodejs and python * fix benchmark * improve rust api, trim template in zen templates * update cargo action * update expression version * compile action * fix action format
78 lines
2.0 KiB
Rust
78 lines
2.0 KiB
Rust
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<Iter<'tokens, Token<'source>>>,
|
|
state: ParserState,
|
|
nodes: Vec<Node<'source>>,
|
|
}
|
|
|
|
impl<'source, 'tokens, T> From<T> 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<Vec<Node<'source>>, 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(())
|
|
}
|
|
}
|