session_rust/
color.rs

1use serde::{ser::Serialize as SerTrait, Deserialize, Serialize};
2use std::fmt;
3use uuid::Uuid;
4
5/// A color with RGBA values and JSON serialization support.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(tag = "type", rename = "Color")]
8pub struct Color {
9    pub guid: String,
10    pub name: String,
11    pub r: u8,
12    pub g: u8,
13    pub b: u8,
14    pub a: u8,
15}
16
17impl Color {
18    /// Create new color.
19    pub fn new(r: u8, g: u8, b: u8, a: u8) -> Self {
20        Color {
21            guid: Uuid::new_v4().to_string(),
22            name: "Color".to_string(),
23            r,
24            g,
25            b,
26            a,
27        }
28    }
29
30    ///////////////////////////////////////////////////////////////////////////////////////////
31    // Presets
32    ///////////////////////////////////////////////////////////////////////////////////////////
33
34    /// Create white color.
35    pub fn white() -> Self {
36        let mut color = Color::new(255, 255, 255, 255);
37        color.name = "white".to_string();
38        color
39    }
40
41    /// Create black color.
42    pub fn black() -> Self {
43        let mut color = Color::new(0, 0, 0, 255);
44        color.name = "black".to_string();
45        color
46    }
47
48    /// Create grey color.
49    pub fn grey() -> Self {
50        let mut color = Color::new(128, 128, 128, 255);
51        color.name = "grey".to_string();
52        color
53    }
54
55    /// Create red color.
56    pub fn red() -> Self {
57        let mut color = Color::new(255, 0, 0, 255);
58        color.name = "red".to_string();
59        color
60    }
61
62    /// Create orange color.
63    pub fn orange() -> Self {
64        let mut color = Color::new(255, 128, 0, 255);
65        color.name = "orange".to_string();
66        color
67    }
68
69    /// Create yellow color.
70    pub fn yellow() -> Self {
71        let mut color = Color::new(255, 255, 0, 255);
72        color.name = "yellow".to_string();
73        color
74    }
75
76    /// Create lime color.
77    pub fn lime() -> Self {
78        let mut color = Color::new(128, 255, 0, 255);
79        color.name = "lime".to_string();
80        color
81    }
82
83    /// Create green color.
84    pub fn green() -> Self {
85        let mut color = Color::new(0, 255, 0, 255);
86        color.name = "green".to_string();
87        color
88    }
89
90    /// Create mint color.
91    pub fn mint() -> Self {
92        let mut color = Color::new(0, 255, 128, 255);
93        color.name = "mint".to_string();
94        color
95    }
96
97    /// Create cyan color.
98    pub fn cyan() -> Self {
99        let mut color = Color::new(0, 255, 255, 255);
100        color.name = "cyan".to_string();
101        color
102    }
103
104    /// Create azure color.
105    pub fn azure() -> Self {
106        let mut color = Color::new(0, 128, 255, 255);
107        color.name = "azure".to_string();
108        color
109    }
110
111    /// Create blue color.
112    pub fn blue() -> Self {
113        let mut color = Color::new(0, 0, 255, 255);
114        color.name = "blue".to_string();
115        color
116    }
117
118    /// Create violet color.
119    pub fn violet() -> Self {
120        let mut color = Color::new(128, 0, 255, 255);
121        color.name = "violet".to_string();
122        color
123    }
124
125    /// Create magenta color.
126    pub fn magenta() -> Self {
127        let mut color = Color::new(255, 0, 255, 255);
128        color.name = "magenta".to_string();
129        color
130    }
131
132    /// Create pink color.
133    pub fn pink() -> Self {
134        let mut color = Color::new(255, 0, 128, 255);
135        color.name = "pink".to_string();
136        color
137    }
138
139    /// Create maroon color.
140    pub fn maroon() -> Self {
141        let mut color = Color::new(128, 0, 0, 255);
142        color.name = "maroon".to_string();
143        color
144    }
145
146    /// Create brown color.
147    pub fn brown() -> Self {
148        let mut color = Color::new(128, 64, 0, 255);
149        color.name = "brown".to_string();
150        color
151    }
152
153    /// Create olive color.
154    pub fn olive() -> Self {
155        let mut color = Color::new(128, 128, 0, 255);
156        color.name = "olive".to_string();
157        color
158    }
159
160    /// Create teal color.
161    pub fn teal() -> Self {
162        let mut color = Color::new(0, 128, 128, 255);
163        color.name = "teal".to_string();
164        color
165    }
166
167    /// Create navy color.
168    pub fn navy() -> Self {
169        let mut color = Color::new(0, 0, 128, 255);
170        color.name = "navy".to_string();
171        color
172    }
173
174    /// Create purple color.
175    pub fn purple() -> Self {
176        let mut color = Color::new(128, 0, 128, 255);
177        color.name = "purple".to_string();
178        color
179    }
180
181    /// Create silver color.
182    pub fn silver() -> Self {
183        let mut color = Color::new(192, 192, 192, 255);
184        color.name = "silver".to_string();
185        color
186    }
187
188    ///////////////////////////////////////////////////////////////////////////////////////////
189    // Details
190    ///////////////////////////////////////////////////////////////////////////////////////////
191
192    /// Convert to float array [0-1].
193    pub fn to_float_array(&self) -> [f32; 4] {
194        [
195            self.r as f32 / 255.0,
196            self.g as f32 / 255.0,
197            self.b as f32 / 255.0,
198            self.a as f32 / 255.0,
199        ]
200    }
201
202    /// Create from float values [0-1].
203    pub fn from_float(r: f32, g: f32, b: f32, a: f32) -> Self {
204        Color::new(
205            (r * 255.0).round() as u8,
206            (g * 255.0).round() as u8,
207            (b * 255.0).round() as u8,
208            (a * 255.0).round() as u8,
209        )
210    }
211
212    ///////////////////////////////////////////////////////////////////////////////////////////
213    // JSON
214    ///////////////////////////////////////////////////////////////////////////////////////////
215
216    /// Serialize to JSON string (for cross-language compatibility)
217    pub fn jsondump(&self) -> Result<String, Box<dyn std::error::Error>> {
218        let mut buf = Vec::new();
219        let formatter = serde_json::ser::PrettyFormatter::with_indent(b"    ");
220        let mut ser = serde_json::Serializer::with_formatter(&mut buf, formatter);
221        SerTrait::serialize(self, &mut ser)?;
222        Ok(String::from_utf8(buf)?)
223    }
224
225    /// Deserialize from JSON string (for cross-language compatibility)
226    pub fn jsonload(json_data: &str) -> Result<Self, Box<dyn std::error::Error>> {
227        Ok(serde_json::from_str(json_data)?)
228    }
229
230    /// Serialize to JSON file
231    pub fn to_json(&self, filepath: &str) -> Result<(), Box<dyn std::error::Error>> {
232        let json = self.jsondump()?;
233        std::fs::write(filepath, json)?;
234        Ok(())
235    }
236
237    /// Deserialize from JSON file
238    pub fn from_json(filepath: &str) -> Result<Self, Box<dyn std::error::Error>> {
239        let json = std::fs::read_to_string(filepath)?;
240        Self::jsonload(&json)
241    }
242}
243
244impl Default for Color {
245    fn default() -> Self {
246        Self::white()
247    }
248}
249
250impl fmt::Display for Color {
251    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252        write!(
253            f,
254            "Color(r={}, g={}, b={}, a={}, name={})",
255            self.r, self.g, self.b, self.a, self.name
256        )
257    }
258}
259
260impl PartialEq for Color {
261    fn eq(&self, other: &Self) -> bool {
262        self.name == other.name
263            && self.r == other.r
264            && self.g == other.g
265            && self.b == other.b
266            && self.a == other.a
267    }
268}
269
270#[cfg(test)]
271#[path = "color_test.rs"]
272mod color_test;