use egui::Color32;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DimensionValue {
#[serde(alias = "$value", alias = "value")]
pub value: String,
#[serde(rename = "$type", default)]
pub token_type: Option<String>,
#[serde(rename = "$description", default)]
pub description: Option<String>,
}
impl DimensionValue {
pub fn from_pt(pt: f32) -> Self {
Self {
value: format!("{:.1}pt", pt),
token_type: Some("dimension".to_string()),
description: None,
}
}
pub fn points(&self) -> f32 {
self.value
.trim_end_matches("pt")
.trim()
.parse::<f32>()
.unwrap_or(0.0)
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ColorValue {
#[serde(alias = "$value", alias = "value")]
pub value: String,
#[serde(rename = "$type", default)]
pub token_type: Option<String>,
#[serde(rename = "$description", default)]
pub description: Option<String>,
}
impl ColorValue {
pub fn hex_or_rgba(&self) -> &str {
&self.value
}
pub fn to_color32(&self) -> Color32 {
parse_color32(&self.value)
}
}
pub fn parse_color32(s: &str) -> Color32 {
let trimmed = s.trim();
if let Some(hex) = trimmed.strip_prefix('#') {
match hex.len() {
6 => {
if let Ok(v) = u32::from_str_radix(hex, 16) {
let r = ((v >> 16) & 0xFF) as u8;
let g = ((v >> 8) & 0xFF) as u8;
let b = (v & 0xFF) as u8;
return Color32::from_rgb(r, g, b);
}
}
8 => {
if let Ok(v) = u32::from_str_radix(hex, 16) {
let r = ((v >> 24) & 0xFF) as u8;
let g = ((v >> 16) & 0xFF) as u8;
let b = ((v >> 8) & 0xFF) as u8;
let a = (v & 0xFF) as u8;
return Color32::from_rgba_unmultiplied(r, g, b, a);
}
}
_ => {}
}
} else if trimmed.starts_with("rgba(") && trimmed.ends_with(')') {
let inside = &trimmed[5..trimmed.len() - 1];
let parts: Vec<&str> = inside.split(',').map(|p| p.trim()).collect();
if parts.len() == 4 {
let r = parts[0].parse::<u8>().unwrap_or(0);
let g = parts[1].parse::<u8>().unwrap_or(0);
let b = parts[2].parse::<u8>().unwrap_or(0);
let a_f = parts[3].parse::<f32>().unwrap_or(1.0);
let a = (a_f.clamp(0.0, 1.0) * 255.0).round() as u8;
return Color32::from_rgba_unmultiplied(r, g, b, a);
}
}
Color32::BLACK
}