use std::fmt; use image; use image::Rgba; use serde_derive::{Serialize, Deserialize}; #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct Colour { pub red: u8, pub green: u8, pub blue: u8, } impl From<&str> for Colour { fn from(str: &str) -> Self { Self::from(hex::decode(&str[str.len() - 6..]).unwrap()) } } impl From> for Colour { fn from(colours: Vec) -> Self { Colour { red: *colours.get(0).unwrap_or(&0), green: *colours.get(1).unwrap_or(&0), blue: *colours.get(2).unwrap_or(&0), } } } impl fmt::Display for Colour { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "#{}", hex::encode([self.red, self.green, self.blue])) } } impl Into> for Colour { fn into(self) -> Vec { vec![self.red, self.green, self.blue] } } impl Into> for Colour { fn into(self) -> Rgba { Rgba::from([self.red, self.green, self.blue, 255]) } } impl Into<[u8; 4]> for Colour { fn into(self) -> [u8; 4] { [self.red, self.green, self.blue, 255] } } #[cfg(test)] mod test { use crate::Colour; #[test] fn test_colour_from_hex() { assert_eq!(Colour::from("#ff00ff" ), Colour { red: 255, green: 0, blue: 255 }); assert_eq!(Colour::from("0xffffff"), Colour { red: 255, green: 255, blue: 255 }); assert_eq!(Colour::from("ffffff" ), Colour { red: 255, green: 255, blue: 255 }); assert_eq!(Colour::from("#010203" ), Colour { red: 1, green: 2, blue: 3 }); assert_eq!(Colour::from("0xa0b0c0"), Colour { red: 160, green: 176, blue: 192 }); } #[test] fn test_colour_to_hex() { assert_eq!(Colour { red: 255, green: 255, blue: 255 }.to_string(), "#ffffff"); assert_eq!(Colour { red: 0, green: 0, blue: 0 }.to_string(), "#000000"); assert_eq!(Colour { red: 0, green: 128, blue: 64 }.to_string(), "#008040"); } #[test] fn test_colour_from_intermediate() { let output = Colour::from(vec![64, 128, 192]); let expected = Colour { red: 64, green: 128, blue: 192 }; assert_eq!(output, expected); } #[test] fn test_colour_to_intermediate() { let output: Vec = Colour { red: 64, green: 128, blue: 192 }.into(); let expected = vec![64, 128, 192]; assert_eq!(output, expected); } }