rshtml_core 0.1.0

RsHtml: A Template Engine for Seamless HTML and Rust Integration.
Documentation
use crate::Node;
use crate::parser::{IParser, RsHtmlParser, Rule};
use pest::error::{Error, ErrorVariant};
use pest::iterators::{Pair, Pairs};
use std::iter::Peekable;

pub struct RustExprParser;

impl IParser for RustExprParser {
    fn parse(parser: &mut RsHtmlParser, pair: Pair<Rule>) -> Result<Node, Box<Error<Rule>>> {
        let pair_span = pair.as_span();

        let mut inner_pairs = pair.into_inner().peekable();
        let mut clauses: Vec<(String, Vec<Node>)> = Vec::new();

        let consume_whitespaces = |inner_p: &mut Peekable<Pairs<Rule>>| {
            while let Some(p) = inner_p.peek() {
                if p.as_rule() == Rule::WHITESPACE {
                    inner_p.next();
                } else {
                    break;
                }
            }
        };

        while inner_pairs.peek().is_some() {
            let head_pair = inner_pairs.next_if(|p| p.as_rule() == Rule::rust_expr_head).ok_or(Error::new_from_span(
                ErrorVariant::CustomError {
                    message: format!("Internal Error: rust_expr expected a head, found {:?}", inner_pairs.peek().map(|p| p.as_rule())),
                },
                pair_span,
            ))?;
            let head = head_pair.as_str().trim().to_string();

            consume_whitespaces(&mut inner_pairs);

            let template_pair = inner_pairs.next_if(|p| p.as_rule() == Rule::inner_template).ok_or(Error::new_from_span(
                ErrorVariant::CustomError {
                    message: format!("Internal Error: rust_expr missing inner_template for head: '{}'", head),
                },
                pair_span,
            ))?;

            let body_nodes = parser.build_nodes_from_pairs(template_pair.into_inner())?;

            clauses.push((head.clone(), body_nodes));

            consume_whitespaces(&mut inner_pairs);
        }

        if clauses.is_empty() {
            return Err(Box::new(Error::new_from_span(
                ErrorVariant::CustomError {
                    message: "Internal Error: rust_expr parsed with no clauses".to_string(),
                },
                pair_span,
            )));
        }

        Ok(Node::RustExpr(clauses))
    }
}