use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RGBColor {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl RGBColor {
#[inline]
pub const fn new(r: u8, g: u8, b: u8) -> Self {
Self { r, g, b }
}
pub fn from_hex(hex: &str) -> Option<Self> {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 {
return None;
}
let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
Some(Self::new(r, g, b))
}
pub fn to_hex(&self) -> String {
format!("{:02X}{:02X}{:02X}", self.r, self.g, self.b)
}
}
impl fmt::Display for RGBColor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "#{}", self.to_hex())
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Length {
emus: i64,
}
impl Length {
#[inline]
pub const fn from_emus(emus: i64) -> Self {
Self { emus }
}
#[inline]
pub fn from_inches(inches: f64) -> Self {
Self {
emus: (inches * 914400.0) as i64,
}
}
#[inline]
pub fn from_cm(cm: f64) -> Self {
Self {
emus: (cm * 360000.0) as i64,
}
}
#[inline]
pub const fn emus(&self) -> i64 {
self.emus
}
#[inline]
pub fn inches(&self) -> f64 {
self.emus as f64 / 914400.0
}
#[inline]
pub fn cm(&self) -> f64 {
self.emus as f64 / 360000.0
}
#[inline]
pub fn points(&self) -> f64 {
self.inches() * 72.0
}
}
impl fmt::Display for Length {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:.2}\"", self.inches())
}
}