use jsonschema::Validator;
use minijinja::{AutoEscape, Environment, UndefinedBehavior};
use serde_json::Value;
use crate::{Error, ValidationErrors, context, schema};
const TEMPLATE_NAME: &str = "view.md";
pub struct View {
validator: Validator,
environment: Environment<'static>,
}
impl View {
pub fn new(schema: &Value, template: &str) -> Result<Self, Error> {
let validator = schema::compile(schema)?;
let mut environment = Environment::new();
environment.set_undefined_behavior(UndefinedBehavior::Strict);
environment.set_auto_escape_callback(|_| AutoEscape::None);
environment.set_keep_trailing_newline(true);
environment
.add_template_owned(TEMPLATE_NAME, template.to_owned())
.map_err(|source| Error::Template {
source: Box::new(source),
})?;
Ok(Self {
validator,
environment,
})
}
pub fn validate(&self, input: &Value) -> Result<(), ValidationErrors> {
ValidationErrors::check(&self.validator, input)
}
pub fn render(&self, input: &Value) -> Result<String, Error> {
self.validate(input)?;
self.environment
.get_template(TEMPLATE_NAME)
.and_then(|template| template.render(context::from_json(input)?))
.map_err(|source| Error::Render {
source: Box::new(source),
})
}
}