use core::fmt::Display;
use crate::shared::style_class::{
color::Color, font_style::FontStyle, font_weight::FontWeight, units::Unit,
};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum StyleProperty {
Fill(Color),
Stroke(Color),
Color(Color),
StrokeWidth(Unit),
FontSize(Unit),
FontWeight(FontWeight),
FontStyle(FontStyle),
StrokeDasharray(u8, u8),
StrokeDashoffset(u16),
Opacity(u8),
BorderRadius(Unit),
}
impl StyleProperty {
#[must_use]
pub fn is_same_type(self, other: StyleProperty) -> bool {
matches!(
(self, other),
(StyleProperty::Fill(_), StyleProperty::Fill(_))
| (StyleProperty::Stroke(_), StyleProperty::Stroke(_))
| (StyleProperty::Color(_), StyleProperty::Color(_))
| (StyleProperty::StrokeWidth(_), StyleProperty::StrokeWidth(_))
| (StyleProperty::FontSize(_), StyleProperty::FontSize(_))
| (StyleProperty::FontWeight(_), StyleProperty::FontWeight(_))
| (StyleProperty::FontStyle(_), StyleProperty::FontStyle(_))
| (StyleProperty::StrokeDasharray(_, _), StyleProperty::StrokeDasharray(_, _))
| (StyleProperty::StrokeDashoffset(_), StyleProperty::StrokeDashoffset(_))
| (StyleProperty::Opacity(_), StyleProperty::Opacity(_))
| (StyleProperty::BorderRadius(_), StyleProperty::BorderRadius(_))
)
}
}
impl Display for StyleProperty {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
StyleProperty::Fill(color) => write!(f, "fill: {}", color.to_hex()),
StyleProperty::Stroke(color) => write!(f, "stroke: {}", color.to_hex()),
StyleProperty::Color(color) => write!(f, "color: {}", color.to_hex()),
StyleProperty::StrokeWidth(unit) => write!(f, "stroke-width: {unit}"),
StyleProperty::FontSize(unit) => write!(f, "font-size: {unit}"),
StyleProperty::FontWeight(weight) => write!(f, "font-weight: {weight}"),
StyleProperty::FontStyle(style) => write!(f, "font-style: {style}"),
StyleProperty::StrokeDasharray(length, gap) => {
write!(f, "stroke-dasharray: {length}, {gap}")
}
StyleProperty::StrokeDashoffset(offset) => write!(f, "stroke-dashoffset: {offset}",),
StyleProperty::Opacity(value) => write!(f, "opacity: {:.2}", f32::from(*value) / 100.0),
StyleProperty::BorderRadius(radius) => write!(f, "rx: {radius}, ry: {radius}"),
}
}
}
#[cfg(test)]
mod tests {
use alloc::format;
use super::*;
#[test]
fn test_style_property_display() {
let color = Color::from((255, 0, 0));
assert_eq!(format!("{}", StyleProperty::Fill(color)), "fill: #ff0000");
assert_eq!(format!("{}", StyleProperty::Stroke(color)), "stroke: #ff0000");
assert_eq!(format!("{}", StyleProperty::Color(color)), "color: #ff0000");
assert_eq!(format!("{}", StyleProperty::StrokeWidth(Unit::Pixel(2))), "stroke-width: 2px");
assert_eq!(format!("{}", StyleProperty::FontSize(Unit::Point(12))), "font-size: 12pt");
assert_eq!(format!("{}", StyleProperty::FontWeight(FontWeight::Bold)), "font-weight: bold");
assert_eq!(
format!("{}", StyleProperty::FontStyle(FontStyle::Italic)),
"font-style: italic"
);
assert_eq!(format!("{}", StyleProperty::StrokeDasharray(5, 2)), "stroke-dasharray: 5, 2");
assert_eq!(format!("{}", StyleProperty::StrokeDashoffset(4)), "stroke-dashoffset: 4");
assert_eq!(format!("{}", StyleProperty::Opacity(50)), "opacity: 0.50");
assert_eq!(format!("{}", StyleProperty::BorderRadius(Unit::Pixel(5))), "rx: 5px, ry: 5px");
}
#[test]
fn test_style_property_is_same_type() {
assert!(
StyleProperty::Fill(Color::from((255, 0, 0)))
.is_same_type(StyleProperty::Fill(Color::from((0, 0, 255))))
);
assert!(
!StyleProperty::Fill(Color::from((255, 0, 0)))
.is_same_type(StyleProperty::Stroke(Color::from((255, 0, 0))))
);
}
}