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 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
71fn 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}