use super::CoreError;
use core::fmt;
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::format;
pub fn invalid_color<T: fmt::Display>(format: T) -> CoreError {
CoreError::InvalidColor(format!("{format}"))
}
pub fn invalid_numeric<T: fmt::Display>(value: T, reason: &str) -> CoreError {
CoreError::InvalidNumeric(format!("'{value}': {reason}"))
}
pub fn invalid_time<T: fmt::Display>(time: T, reason: &str) -> CoreError {
CoreError::InvalidTime(format!("'{time}': {reason}"))
}
pub fn validate_color_format(color: &str) -> Result<(), CoreError> {
let trimmed = color.trim();
if trimmed.is_empty() {
return Err(invalid_color("Empty color value"));
}
if trimmed.starts_with("&H") || trimmed.starts_with("&h") {
let hex_part = if trimmed.ends_with('&') {
&trimmed[2..trimmed.len() - 1]
} else {
&trimmed[2..]
};
if hex_part.len() != 6 && hex_part.len() != 8 {
return Err(invalid_color(format!(
"Hex color '{trimmed}' must be 6 or 8 characters after &H"
)));
}
if !hex_part.chars().all(|c| c.is_ascii_hexdigit()) {
return Err(invalid_color(format!(
"Invalid hex digits in color '{trimmed}'"
)));
}
} else {
if trimmed.parse::<u32>().is_err() {
return Err(invalid_color(format!(
"Color '{trimmed}' is neither valid hex (&HBBGGRR) nor decimal"
)));
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn color_error_creation() {
let error = invalid_color("invalid");
assert!(matches!(error, CoreError::InvalidColor(_)));
}
#[test]
fn numeric_error_creation() {
let error = invalid_numeric("abc", "not a number");
assert!(matches!(error, CoreError::InvalidNumeric(_)));
}
#[test]
fn time_error_creation() {
let error = invalid_time("invalid", "wrong format");
assert!(matches!(error, CoreError::InvalidTime(_)));
}
#[test]
fn validate_hex_color() {
assert!(validate_color_format("&H00FF00FF").is_ok());
assert!(validate_color_format("&H00FF00FF&").is_ok());
assert!(validate_color_format("&h00ff00ff").is_ok());
assert!(validate_color_format("&HFFFFFF").is_ok());
}
#[test]
fn validate_decimal_color() {
assert!(validate_color_format("16777215").is_ok()); assert!(validate_color_format("0").is_ok()); }
#[test]
fn invalid_hex_color() {
assert!(validate_color_format("&HGG0000").is_err());
assert!(validate_color_format("&H123").is_err()); assert!(validate_color_format("&H123456789").is_err()); }
#[test]
fn invalid_color_format() {
assert!(validate_color_format("").is_err());
assert!(validate_color_format("invalid").is_err());
assert!(validate_color_format("#FF0000").is_err()); }
}