cdoc/templates/
precompiled.rs

1use anyhow::{anyhow, Context};
2use serde::{Deserialize, Serialize};
3use std::io::Write;
4use tera::Context as TCtx;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(rename_all = "lowercase")]
8pub enum PrecompiledFormat {
9    Html,
10    Markdown,
11    LaTeX,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15#[serde(rename_all = "snake_case")]
16pub enum PrecompiledTemplate {
17    Paragraph,
18    Emphasis,
19    Strong,
20    HardBreak,
21    SoftBreak,
22}
23
24impl PrecompiledTemplate {
25    pub fn render(
26        &self,
27        format: &PrecompiledFormat,
28        ctx: &TCtx,
29        mut buf: impl Write,
30    ) -> anyhow::Result<()> {
31        match self {
32            PrecompiledTemplate::Paragraph => match format {
33                PrecompiledFormat::Html => write!(
34                    &mut buf,
35                    "<p>{}</p>",
36                    ctx.get("value")
37                        .ok_or(anyhow!("missing value"))?
38                        .as_str()
39                        .unwrap()
40                )
41                .context("rendering"),
42                PrecompiledFormat::Markdown => writeln!(
43                    &mut buf,
44                    "{}",
45                    ctx.get("value")
46                        .ok_or(anyhow!("missing value"))?
47                        .as_str()
48                        .unwrap()
49                )
50                .context("rendering"),
51                _ => Err(anyhow!(format!("unsupported format {:?}", format))),
52            },
53            PrecompiledTemplate::Emphasis => match format {
54                PrecompiledFormat::Html => write!(
55                    &mut buf,
56                    "<em>{}</em>",
57                    ctx.get("value")
58                        .ok_or(anyhow!("missing value"))?
59                        .as_str()
60                        .unwrap()
61                )
62                .context("rendering"),
63                PrecompiledFormat::Markdown => write!(
64                    &mut buf,
65                    "_{}_",
66                    ctx.get("value")
67                        .ok_or(anyhow!("missing value"))?
68                        .as_str()
69                        .unwrap()
70                )
71                .context("rendering"),
72                _ => Err(anyhow!(format!("unsupported format {:?}", format))),
73            },
74            PrecompiledTemplate::Strong => match format {
75                PrecompiledFormat::Html => write!(
76                    &mut buf,
77                    "<strong>{}</strong>",
78                    ctx.get("value")
79                        .ok_or(anyhow!("missing value"))?
80                        .as_str()
81                        .unwrap()
82                )
83                .context("rendering"),
84                PrecompiledFormat::Markdown => write!(
85                    &mut buf,
86                    "**{}**",
87                    ctx.get("value")
88                        .ok_or(anyhow!("missing value"))?
89                        .as_str()
90                        .unwrap()
91                )
92                .context("rendering"),
93                _ => Err(anyhow!(format!("unsupported format {:?}", format))),
94            },
95            PrecompiledTemplate::HardBreak => match format {
96                PrecompiledFormat::Html => write!(&mut buf, "<br>",).context("rendering"),
97                PrecompiledFormat::Markdown => write!(&mut buf, "\n\n",).context("rendering"),
98                _ => Err(anyhow!(format!("unsupported format {:?}", format))),
99            },
100            PrecompiledTemplate::SoftBreak => match format {
101                PrecompiledFormat::Html => write!(&mut buf, "",).context("rendering"),
102                PrecompiledFormat::Markdown => writeln!(&mut buf).context("rendering"),
103                _ => Err(anyhow!(format!("unsupported format {:?}", format))),
104            },
105        }?;
106        Ok(())
107    }
108}