tinted_builder/template.rs
1mod base16;
2mod tinted8;
3
4use crate::{error::TintedBuilderError, scheme::Scheme};
5
6/// A struct representing a template that can be rendered with the provided color scheme.
7///
8/// The `Template` struct holds the content of the template and the scheme used to render it. It
9/// provides methods to create a new template and render it into a `String` using the specified
10/// color scheme.
11pub struct Template {
12 content: String,
13 scheme: Scheme,
14}
15
16impl Template {
17 /// Creates a new `Template` instance.
18 ///
19 /// # Arguments
20 ///
21 /// * `content` - A `String` representing the content of the template.
22 /// * `scheme` - A `Scheme` enum that determines which color scheme to use when rendering the template.
23 ///
24 /// # Returns
25 ///
26 /// A new `Template` instance with the provided content and scheme.
27 #[must_use]
28 pub const fn new(content: String, scheme: Scheme) -> Self {
29 Self { content, scheme }
30 }
31
32 /// Renders the template into a `String` using the provided color scheme.
33 ///
34 /// This method applies the specified `Scheme` to the template content, converting placeholders
35 /// in the content to their corresponding values from the scheme context.
36 ///
37 /// # Errors
38 ///
39 /// Returns a `TintedBuilderError` if the rendering process fails. This could happen if the
40 /// content contains placeholders that cannot be resolved using the scheme context.
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// use tinted_builder::{Template, Scheme};
46 ///
47 /// let scheme_yaml = r#"
48 /// system: "base16"
49 /// name: "Some name"
50 /// author: "Some author"
51 /// variant: "dark"
52 /// palette:
53 /// base00: "241b26"
54 /// base01: "2f2a3f"
55 /// base02: "46354a"
56 /// base03: "6c3cb2"
57 /// base04: "7e5f83"
58 /// base05: "eed5d9"
59 /// base06: "d9c2c6"
60 /// base07: "e4ccd0"
61 /// base08: "877bb6"
62 /// base09: "de5b44"
63 /// base0A: "a84a73"
64 /// base0B: "c965bf"
65 /// base0C: "9c5fce"
66 /// base0D: "6a9eb5"
67 /// base0E: "78a38f"
68 /// base0F: "a3a079"
69 /// "#;
70 /// let template = Template::new(
71 /// r#"{{scheme-system}} scheme name is "{{scheme-name}}" and first color is #{{base00-hex}}"#.to_string(),
72 /// Scheme::from_yaml(scheme_yaml).unwrap()
73 /// );
74 /// let rendered = template.render().unwrap();
75 ///
76 /// assert_eq!(
77 /// rendered,
78 /// r#"base16 scheme name is "Some name" and first color is #241b26"#
79 /// );
80 /// ```
81 pub fn render(&self) -> Result<String, TintedBuilderError> {
82 match self.scheme {
83 Scheme::Base16(ref scheme) => {
84 let ctx = base16::to_template_context(&scheme.into());
85 let rendered = base16::render(&self.content, &ctx)?;
86 Ok(rendered)
87 }
88 Scheme::Base24(ref scheme) => {
89 let ctx = base16::to_template_context(&scheme.into());
90 let rendered = base16::render(&self.content, &ctx)?;
91 Ok(rendered)
92 }
93 Scheme::Tinted8(ref scheme) => {
94 let ctx = tinted8::to_template_context(scheme)?;
95 let rendered = tinted8::render(&self.content, &ctx)?;
96 Ok(rendered)
97 }
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use crate::{Scheme, Template};
105
106 const SCHEME: &str = r##"
107system: "base16"
108name: "Test"
109slug: "test"
110author: "Me"
111variant: "dark"
112palette:
113 base00: "#000000"
114 base01: "#111111"
115 base02: "#222222"
116 base03: "#333333"
117 base04: "#444444"
118 base05: "#555555"
119 base06: "#666666"
120 base07: "#777777"
121 base08: "#888888"
122 base09: "#999999"
123 base0A: "#aaaaaa"
124 base0B: "#bbbbbb"
125 base0C: "#cccccc"
126 base0D: "#dddddd"
127 base0E: "#eeeeee"
128 base0F: "#ffffff"
129"##;
130
131 #[test]
132 fn renders_plain_text() {
133 #[allow(clippy::unwrap_used)]
134 let tpl = Template::new(
135 "Hello".to_string(),
136 Scheme::Base16(serde_yaml::from_str(SCHEME).unwrap()),
137 );
138 assert_eq!(tpl.render().expect("unable to render"), "Hello");
139 }
140
141 #[test]
142 fn renders_base16_variable_hex() {
143 #[allow(clippy::unwrap_used)]
144 let tpl = Template::new(
145 "#{{base0A-hex}}".to_string(),
146 Scheme::Base16(serde_yaml::from_str(SCHEME).unwrap()),
147 );
148 assert_eq!(tpl.render().expect("unable to render"), "#aaaaaa");
149 }
150}