builder_rust/library/
template.rs

1// builder-rust is a Tinted Theming template builder which uses color
2// schemes to generate theme files.
3// Copyright (C) 2024  Tinted Theming
4
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18use anyhow::Result;
19use ramhorns::Template as RamhornsTemplate;
20use std::collections::HashMap;
21use std::path::Path;
22
23use crate::utils::write_to_file;
24use crate::Scheme;
25
26pub struct Template {
27    content: String,
28}
29
30impl Template {
31    pub fn new(content: String) -> Result<Template> {
32        Ok(Template { content })
33    }
34
35    fn to_template_context(scheme: &Scheme) -> HashMap<String, String> {
36        let mut context = HashMap::new();
37
38        context.insert("scheme-name".to_string(), scheme.name.clone());
39        context.insert("scheme-author".to_string(), scheme.author.clone());
40        context.insert(
41            "scheme-description".to_string(),
42            scheme.description.clone().unwrap_or_default(),
43        );
44        context.insert("scheme-slug".to_string(), scheme.slug.clone());
45        context.insert(
46            "scheme-slug-underscored".to_string(),
47            scheme.slug.replace('-', "_"),
48        );
49        context.insert("scheme-system".to_string(), scheme.system.clone());
50        context.insert("scheme-variant".to_string(), scheme.variant.clone());
51        context.insert(
52            format!("scheme-is-{}-variant", scheme.variant),
53            "true".to_string(),
54        );
55
56        for (name, color) in scheme.palette.iter() {
57            let hex = color.hex.clone();
58            let rgb = color.rgb;
59
60            context.insert(
61                format!("{}-hex", name),
62                format!("{}{}{}", color.hex.0, color.hex.1, color.hex.2),
63            );
64            context.insert(
65                format!("{}-hex-bgr", name),
66                format!("{}{}{}", color.hex.2, color.hex.1, color.hex.0),
67            );
68            context.insert(format!("{}-hex-r", name), hex.0);
69            context.insert(format!("{}-hex-g", name), hex.1);
70            context.insert(format!("{}-hex-b", name), hex.2);
71            context.insert(format!("{}-rgb-r", name), rgb.0.to_string());
72            context.insert(format!("{}-rgb-g", name), rgb.1.to_string());
73            context.insert(format!("{}-rgb-b", name), rgb.2.to_string());
74            context.insert(format!("{}-dec-r", name), (rgb.0 / 255).to_string());
75            context.insert(format!("{}-dec-g", name), (rgb.1 / 255).to_string());
76            context.insert(format!("{}-dec-b", name), (rgb.2 / 255).to_string());
77        }
78
79        context
80    }
81
82    pub fn render_to_file(&self, output_path: &Path, scheme: &Scheme) -> Result<&Self> {
83        let tpl = RamhornsTemplate::new(self.content.clone()).unwrap();
84        let context = Self::to_template_context(scheme);
85        let rendered = tpl.render(&context);
86
87        write_to_file(output_path, &rendered)?;
88
89        Ok(self)
90    }
91}