use anvil::Anvil;
use serde::Serialize;
pub mod extensions;
pub trait Earth: Serialize {
fn tera(&self, writer: &mut (impl std::io::Write + ?Sized)) -> tera::Result<()>;
}
pub struct Firma<'a, T: Earth>(&'a T);
impl<T: Earth> Anvil for Firma<'_, T> {
type Error = tera::Error;
fn anvil(&self, writer: &mut (impl std::io::Write + ?Sized)) -> Result<(), Self::Error> {
self.0.tera(writer)
}
}
pub mod prelude {
pub use crate::extensions::{
append::{append, TeraAppendExt},
generate::{generate, TeraGenerateExt},
};
pub use crate::Earth;
}
#[macro_export]
macro_rules! make_tera_template {
($struct:ident, $template:expr, $tera:expr) => {
impl Earth for $struct {
fn tera(&self, writer: &mut (impl std::io::Write + ?Sized)) -> tera::Result<()> {
let context = tera::Context::from_serialize(self).unwrap();
$tera.render_to($template, &context, writer)
}
}
};
}
#[cfg(test)]
mod test {
use std::sync::LazyLock;
use crate::Firma;
static TEMPLATES: LazyLock<Tera> = LazyLock::new(|| {
let mut tera = Tera::default();
tera.add_raw_template("test", "Hello, {{ name }}!\n")
.unwrap();
tera
});
use super::prelude::*;
use super::*;
use crate::make_tera_template;
use serde::Serialize;
use tera::Tera;
#[derive(Serialize)]
struct TestEarth {
name: String,
}
make_tera_template!(TestEarth, "test", TEMPLATES);
#[test]
fn it_can_render_template() {
let earth = TestEarth {
name: "World".to_string(),
};
let mut buf = Vec::new();
let firma = Firma(&earth);
firma.anvil(&mut buf).unwrap();
let result = String::from_utf8(buf).unwrap();
assert_eq!(result, "Hello, World!\n");
}
}