dwind_build/
colors.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::fs;
4use std::io::Write;
5use std::path::Path;
6
7#[derive(Serialize, Deserialize)]
8pub struct Color {
9    pub name: String,
10    pub shades: HashMap<u32, String>,
11}
12
13#[derive(Serialize, Deserialize)]
14pub struct ColorFile {
15    pub colors: Vec<Color>,
16}
17
18pub fn render_color_json_file_to_rust_file(
19    color_file_path: impl AsRef<Path>,
20    colors_out_file: impl AsRef<Path>,
21) {
22    // Generate the colors file
23    let color_file = fs::read_to_string(color_file_path).unwrap();
24    let colors: ColorFile = serde_json::from_str(&color_file).unwrap();
25
26    let mut colors_out_file = fs::File::create(colors_out_file).unwrap();
27
28    for color in colors.colors.iter() {
29        let _ = colors_out_file
30            .write(render_color(color, "bg", "bg-color-").as_bytes())
31            .unwrap();
32        let _ = colors_out_file
33            .write(render_color(color, "text", "text-color-").as_bytes())
34            .unwrap();
35        let _ = colors_out_file
36            .write(render_color(color, "border", "border-color-").as_bytes())
37            .unwrap();
38
39        let _ = colors_out_file
40            .write(render_color(color, "gradient-from", "gradient-from-").as_bytes())
41            .unwrap();
42        let _ = colors_out_file
43            .write(render_color(color, "gradient-to", "gradient-to-").as_bytes())
44            .unwrap();
45        let _ = colors_out_file
46            .write(render_color(color, "from", "gradient-from-").as_bytes())
47            .unwrap();
48
49        let _ = colors_out_file
50            .write(render_color(color, "to", "gradient-to-").as_bytes())
51            .unwrap();
52
53        let _ = colors_out_file
54            .write(render_color(color, "fill", "fill-").as_bytes())
55            .unwrap();
56
57        let _ = colors_out_file
58            .write(render_color(color, "stroke", "stroke-").as_bytes())
59            .unwrap();
60
61        let _ = colors_out_file
62            .write(render_color(color, "ring", "ring-").as_bytes())
63            .unwrap();
64    }
65
66    let _ = colors_out_file
67        .write(render_dwind_colors(&colors).as_bytes())
68        .unwrap();
69}
70
71// render a once cell with a hash map of all the colors
72fn render_dwind_colors(colors: &ColorFile) -> String {
73    let colors_string = colors
74        .colors
75        .iter()
76        .map(|color| {
77            let shades = color
78                .shades
79                .iter()
80                .map(|(shade, value)| format!("({shade}, \"{value}\".to_string())"))
81                .collect::<Vec<_>>()
82                .join(", ");
83
84            format!(
85                "(\"{}\".to_string(), std::collections::BTreeMap::from([{shades}]))",
86                color.name
87            )
88        })
89        .collect::<Vec<_>>()
90        .join(",\n");
91
92    let color_constants = get_color_constants(colors);
93
94    let dwind_colors = format!(
95        r#"#[deprecated]
96pub static DWIND_COLORS: once_cell::sync::Lazy<std::collections::BTreeMap<String, std::collections::BTreeMap<u32, String>>> = once_cell::sync::Lazy::new(|| {{
97    std::collections::BTreeMap::from([
98    {colors_string}
99])
100}});"#
101    );
102
103    format!("{dwind_colors}\npub mod codes {{\n{color_constants}\n}}")
104}
105
106fn get_color_constants(colors: &ColorFile) -> String {
107    colors
108        .colors
109        .iter()
110        .map(|color| {
111            color
112                .shades
113                .iter()
114                .map(|(intensity, value)| {
115                    format!(
116                        "pub const {}_{}: &str = \"{}\";\n",
117                        color.name.to_uppercase().replace("-", "_"),
118                        intensity,
119                        value
120                    )
121                })
122                .collect::<Vec<_>>()
123                .join("\n")
124        })
125        .collect::<Vec<_>>()
126        .join("\n")
127}
128
129fn render_color(color: &Color, prefix: &str, generator: &str) -> String {
130    let shades = color
131        .shades
132        .iter()
133        .map(|(intensity, value)| format!("    (\"{}-{intensity}\", \"{value}\")", color.name))
134        .collect::<Vec<String>>()
135        .join(",\n");
136
137    format!(
138        r#"dwgenerate_map!("{prefix}", "{generator}", [
139{shades}
140]);"#,
141    )
142}