pub mod ast;
pub mod error;
pub mod eval;
mod parser;
pub mod registry;
pub use ast::span::{Span, Spanned};
pub use ast::template::Template;
pub use ast::value::Value;
pub use error::{EvalError, EvalErrorKind, ParseError};
pub use eval::{EvalContext, EvalOptions, SimpleContext, evaluate, evaluate_with_options, eval_expr_value};
pub use parser::{parse, parse_expr};
pub use registry::{ClosureCommand, ClosureProcessor, Registry, WeaverCommand, WeaverProcessor};
pub fn render(
source: &str,
ctx: &mut impl EvalContext,
registry: &Registry,
) -> Result<String, RenderError> {
let template = parser::parse(source).map_err(RenderError::Parse)?;
evaluate(&template, ctx, registry).map_err(RenderError::Eval)
}
pub fn render_with_options(
source: &str,
ctx: &mut impl EvalContext,
registry: &Registry,
options: EvalOptions,
) -> Result<String, RenderError> {
let template = parser::parse(source).map_err(RenderError::Parse)?;
evaluate_with_options(&template, ctx, registry, options).map_err(RenderError::Eval)
}
#[derive(Debug)]
pub enum RenderError {
Parse(Vec<ParseError>),
Eval(EvalError),
}
impl std::fmt::Display for RenderError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
RenderError::Parse(errors) => {
for e in errors {
writeln!(f, "{e}")?;
}
Ok(())
}
RenderError::Eval(e) => write!(f, "{e}"),
}
}
}
impl std::error::Error for RenderError {}
pub struct CompiledTemplate {
template: Template,
}
impl CompiledTemplate {
pub fn compile(source: &str) -> Result<Self, Vec<ParseError>> {
let template = parser::parse(source)?;
Ok(Self { template })
}
pub fn evaluate(
&self,
ctx: &mut impl EvalContext,
registry: &Registry,
) -> Result<String, EvalError> {
evaluate(&self.template, ctx, registry)
}
pub fn evaluate_with_options(
&self,
ctx: &mut impl EvalContext,
registry: &Registry,
options: EvalOptions,
) -> Result<String, EvalError> {
evaluate_with_options(&self.template, ctx, registry, options)
}
pub fn ast(&self) -> &Template {
&self.template
}
}