pub const COLORS : [&str; 16] = [ "#000000", "#1D2B53", "#7E2553", "#008751", "#AB5236", "#5F574F", "#C2C3C7", "#FFF1E8", "#FF004D", "#FFA300", "#FFEC27", "#00E436", "#29ADFF", "#83769C", "#FF77A8", "#FFCCAA" ]; #[derive(Clone,Copy,PartialEq,Debug)] pub struct Color([u8 ; 3]); impl From for String { fn from(color: Color) -> String { format!("#{:02x}{:02x}{:02x}", color.0[0], color.0[1], color.0[2]) } } impl TryFrom for Color { type Error = &'static str; fn try_from(s: String) -> Result { let ("#", rest) = s[..].split_at(1) else { return Err("Badly formated color: should start with '#'"); }; if rest.len() != 6 { return Err("Badly formated color"); } let Ok(r) = u8::from_str_radix(&rest[0..2], 16) else { return Err("Badly formated color"); }; let Ok(g) = u8::from_str_radix(&rest[2..4], 16) else { return Err("Badly formated color"); }; let Ok(b) = u8::from_str_radix(&rest[4..6], 16) else { return Err("Badly formated color"); }; Ok(Color([r,g,b])) } } #[test] fn test_string_to_color() { let c : Result = "#ff0042".to_string().try_into(); assert_eq!(c, Ok(Color([0xff, 0x00, 0x42]))); let c : Result = "ff0042".to_string().try_into(); assert_eq!(c, Err("Badly formated color: should start with '#'")); let c : Result = "#ff004242".to_string().try_into(); assert_eq!(c, Err("Badly formated color")); let c : Result = "#ffg042".to_string().try_into(); assert_eq!(c, Err("Badly formated color")); } #[test] fn test_color_to_string() { let s : String = Color([0xff, 0x00, 0x42]).into(); assert_eq!(s, "#ff0042"); }