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()); 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}