scalar_doc/
lib.rs

1use anyhow::Result;
2use serde::Serialize;
3use tera::{Context, Tera};
4use crate::favicon::{Favicon, FaviconMimeType};
5
6pub mod configuration;
7pub mod favicon;
8#[cfg(feature = "actix")]
9pub mod scalar_actix;
10
11static TEMPLATE: &str = include_str!("templates/template.html");
12
13#[derive(Clone)]
14pub enum Theme {
15    Alternate,
16    Default,
17    Moon,
18    Purple,
19    Solarized,
20    BluePlanet,
21    Saturn,
22    Kepler,
23    Mars,
24    DeepSpace,
25    Elysiajs,
26    Fastify,
27    None,
28}
29
30impl Serialize for Theme {
31    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
32    where
33        S: serde::ser::Serializer,
34    {
35        serializer.serialize_str(self.as_str())
36    }
37}
38
39impl Theme {
40    fn as_str(&self) -> &str {
41        match self {
42            Theme::Alternate => "alternate",
43            Theme::Default => "default",
44            Theme::Moon => "moon",
45            Theme::Purple => "purple",
46            Theme::Solarized => "solarized",
47            Theme::BluePlanet => "blue-planet",
48            Theme::Saturn => "saturn",
49            Theme::Kepler => "kepler",
50            Theme::Mars => "mars",
51            Theme::DeepSpace => "deep-space",
52            Theme::Elysiajs => "elysiajs",
53            Theme::Fastify => "fastify",
54            Theme::None => "none",
55        }
56    }
57}
58
59pub struct Documentation {
60    title: String,
61    favicon: Favicon,
62    content: String,
63    configuration: configuration::Configuration,
64}
65
66impl Documentation {
67    pub fn new(title: &str, content: &str) -> Self {
68        Self {
69            title: title.to_string(),
70            favicon: Favicon::default(),
71            content: content.to_string(),
72            configuration: configuration::Configuration::default(),
73        }
74    }
75
76    pub fn favicon(&mut self, favicon: &str, mime: FaviconMimeType) -> &mut Self {
77        self.favicon = Favicon::new(favicon.to_string(), mime);
78        self
79    }
80
81    pub fn favicon_raw(&mut self, favicon: Favicon) -> &mut Self {
82        self.favicon = favicon;
83        self
84    }
85
86    pub fn theme(&mut self, theme: Theme) -> &mut Self {
87        self.configuration.theme = Some(theme);
88        self
89    }
90
91    pub fn build(&self) -> Result<String, anyhow::Error> {
92        let configuration = serde_json::to_string(&self.configuration)?;
93        templatize(self.content.clone(), self.favicon.clone(), self.title.clone(), configuration)
94    }
95}
96
97pub fn templatize(
98    content: String,
99    favicon: Favicon,
100    title: String,
101    configuration: String,
102) -> Result<String, anyhow::Error> {
103    let mut tera = Tera::default();
104    tera.add_raw_template("template.html", TEMPLATE)?;
105
106    let mut context = Context::new();
107    context.insert("documentation", &content);
108    context.insert("favicon", favicon.favicon()); // it's already &String
109    context.insert("favicon_mime", &favicon.mime());
110    context.insert("title", &title);
111    context.insert("configuration", &configuration);
112
113    let parsed_doc = tera.render("template.html", &context)?;
114
115    Ok(parsed_doc)
116}