use crate::errors::NamedColorsError;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Deserialize, Serialize, Debug)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
}
pub fn load_colors() -> Result<HashMap<String, Color>, NamedColorsError> {
let data = include_str!("../assets/named_colors.json"); let color_map: HashMap<String, Color> =
serde_json::from_str(data).map_err(NamedColorsError::ParseError)?;
Ok(color_map)
}
pub fn load_colors_from_file(json_data: &str) -> Result<HashMap<String, Color>, NamedColorsError> {
let color_map: HashMap<String, Color> =
serde_json::from_str(json_data).map_err(NamedColorsError::ParseError)?;
Ok(color_map)
}
pub fn add_color(
color_map: &mut HashMap<String, Color>,
color_name: &str,
r: u8,
g: u8,
b: u8,
) -> Result<(), NamedColorsError> {
let color_name = color_name.to_lowercase();
if color_map.contains_key(&color_name) {
return Err(NamedColorsError::Custom(format!(
"The color '{}' already exists.",
color_name
)));
}
color_map.insert(color_name.clone(), Color { r, g, b });
Ok(())
}
pub fn get_color_by_name(
color_map: &HashMap<String, Color>,
color_name: &str,
) -> Option<(u8, u8, u8)> {
let color_name = color_name.to_lowercase();
color_map
.get(&color_name)
.map(|color| (color.r, color.g, color.b))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_color_by_name() {
let color_map = load_colors().unwrap();
let color = get_color_by_name(&color_map, "red");
assert_eq!(color, Some((255, 0, 0))); }
#[test]
fn test_get_color_by_invalid_name() {
let color_map = load_colors().unwrap();
let color = get_color_by_name(&color_map, "invalid_color");
assert_eq!(color, None); }
#[test]
fn test_get_color_case_insensitive() {
let color_map = load_colors().unwrap();
let color = get_color_by_name(&color_map, "Red");
assert_eq!(color, Some((255, 0, 0)));
let color_lowercase = get_color_by_name(&color_map, "red");
assert_eq!(color_lowercase, Some((255, 0, 0))); }
#[test]
fn test_add_new_color() {
let mut color_map = load_colors().unwrap();
let result = add_color(&mut color_map, "sunset_orange", 255, 94, 77);
assert!(result.is_ok(), "Failed to add the new color.");
let color = get_color_by_name(&color_map, "sunset_orange");
assert_eq!(color, Some((255, 94, 77))); }
#[test]
fn test_load_colors_from_file() {
let json_data = r#"{"blue": {"r": 0, "g": 0, "b": 255}}"#;
let color_map = load_colors_from_file(json_data).unwrap();
let color = get_color_by_name(&color_map, "blue");
assert_eq!(color, Some((0, 0, 255))); }
#[test]
fn test_add_duplicate_color() {
let mut color_map = load_colors().unwrap();
let result = add_color(&mut color_map, "blue", 0, 0, 255);
assert!(result.is_ok(), "Failed to add the new color.");
let result = add_color(&mut color_map, "blue", 255, 0, 0);
assert!(result.is_err(), "Failed to detect duplicate color.");
assert_eq!(
result.err().unwrap().to_string(),
"The color 'blue' already exists."
);
}
}