1use anvil::Anvil;
2use serde::Serialize;
3
4pub mod extensions;
5
6pub trait Earth: Serialize {
9 fn tera(&self, writer: &mut (impl std::io::Write + ?Sized)) -> tera::Result<()>;
10}
11
12pub struct Firma<'a, T: Earth>(&'a T);
13
14impl<T: Earth> Anvil for Firma<'_, T> {
15 type Error = tera::Error;
16 fn anvil(&self, writer: &mut (impl std::io::Write + ?Sized)) -> Result<(), Self::Error> {
17 self.0.tera(writer)
18 }
19}
20
21pub mod prelude {
22 pub use crate::extensions::{
23 append::{append, TeraAppendExt},
24 generate::{generate, TeraGenerateExt},
25 };
26 pub use crate::Earth;
27}
28
29#[cfg(test)]
30mod test {
31 use std::sync::LazyLock;
32
33 use crate::Firma;
34
35 static TEMPLATES: LazyLock<Tera> = LazyLock::new(|| {
36 let mut tera = Tera::default();
37 tera.add_raw_template("test", "Hello, {{ name }}!\n")
38 .unwrap();
39 tera
40 });
41
42 use super::*;
43 use serde::Serialize;
44 use tera::Tera;
45
46 #[derive(Serialize)]
47 struct TestEarth {
48 name: String,
49 }
50
51 impl Earth for TestEarth {
52 fn tera(&self, writer: &mut (impl std::io::Write + ?Sized)) -> tera::Result<()> {
53 let context = ::tera::Context::from_serialize(self)?;
54 TEMPLATES.render_to("test", &context, writer)
56 }
57 }
58
59 #[test]
60 fn it_can_render_template() {
61 let earth = TestEarth {
62 name: "World".to_string(),
63 };
64
65 let mut buf = Vec::new();
66
67 let firma = Firma(&earth);
68
69 firma.anvil(&mut buf).unwrap();
70
71 let result = String::from_utf8(buf).unwrap();
72
73 assert_eq!(result, "Hello, World!\n");
74 }
75}