danceinterpreter_rs/dataloading/
staticinfo.rs1use iced::Color;
2use serde::{Deserialize, Serialize};
3
4#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
5#[serde(default)]
6pub struct StaticInfo {
7 pub name: String,
8 pub is_favorite: bool,
9 #[serde(with = "color_format", default)]
10 pub color: Option<Color>,
11}
12
13impl StaticInfo {
14 #[allow(dead_code)]
15 pub fn new(name: String) -> Self {
16 StaticInfo {
17 name,
18 is_favorite: false,
19 color: None,
20 }
21 }
22}
23
24mod color_format {
25 use super::*;
26 use serde::{Deserialize, Deserializer, Serializer};
27
28 pub fn serialize<S>(color: &Option<Color>, serializer: S) -> Result<S::Ok, S::Error>
29 where
30 S: Serializer,
31 {
32 match color {
33 Some(c) => {
34 let r = (c.r * 255.0) as u8;
35 let g = (c.g * 255.0) as u8;
36 let b = (c.b * 255.0) as u8;
37 let hex = format!("#{:02X}{:02X}{:02X}", r, g, b);
38 serializer.serialize_some(&hex)
39 }
40 None => serializer.serialize_none(),
41 }
42 }
43
44 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Color>, D::Error>
45 where
46 D: Deserializer<'de>,
47 {
48 let s: Option<String> = Option::deserialize(deserializer)?;
49 match s {
50 Some(hex) => {
51 let hex = hex.trim_start_matches('#');
52 if hex.len() != 6 {
53 return Ok(None);
54 }
55 let (Ok(r), Ok(g), Ok(b)) = (
56 u8::from_str_radix(&hex[0..2], 16),
57 u8::from_str_radix(&hex[2..4], 16),
58 u8::from_str_radix(&hex[4..6], 16),
59 ) else {
60 return Ok(None);
61 };
62 Ok(Some(Color::from_rgb8(r, g, b)))
63 }
64 None => Ok(None),
65 }
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_color_serialization() {
75 let static_info = StaticInfo {
76 name: "Waltz".to_string(),
77 is_favorite: true,
78 color: Some(Color::from_rgb8(255, 0, 128)),
79 };
80
81 let json = serde_json::to_string(&static_info).unwrap();
82 assert!(json.contains("\"color\":\"#FF0080\""));
83 }
84
85 #[test]
86 fn test_color_deserialization() {
87 let json = r##"{"name":"Tango","is_favorite":false,"color":"#00FF00"}"##;
88 let static_info: StaticInfo = serde_json::from_str(json).unwrap();
89
90 assert_eq!(static_info.name, "Tango");
91 assert_eq!(static_info.color, Some(Color::from_rgb8(0, 255, 0)));
92 }
93
94 #[test]
95 fn test_color_deserialization_invalid() {
96 let json = r##"{"name":"Tango","is_favorite":false,"color":"invalid"}"##;
97 let static_info: StaticInfo = serde_json::from_str(json).unwrap();
98
99 assert_eq!(static_info.color, None);
100 }
101}