use std::fmt::Write as _;
fn channel(value: f64) -> String {
if value.is_nan() {
"none".to_string()
} else {
format!("{value}")
}
}
fn channel_pct(value: f64) -> String {
if value.is_nan() {
"none".to_string()
} else {
format!("{}%", value * 100.0)
}
}
fn alpha_suffix(alpha: Option<f64>) -> String {
match alpha {
Some(a) if a.is_finite() && a < 1.0 => format!(" / {a}"),
_ => String::new(),
}
}
pub fn format_color_fn(id: &str, channels: &[f64; 3], alpha: Option<f64>) -> String {
let mut out = String::with_capacity(32);
out.push_str("color(");
out.push_str(id);
for &c in channels {
out.push(' ');
out.push_str(&channel(c));
}
out.push_str(&alpha_suffix(alpha));
out.push(')');
out
}
pub fn format_color_fn_4(id: &str, channels: &[f64; 4], alpha: Option<f64>) -> String {
let mut out = String::with_capacity(36);
out.push_str("color(");
out.push_str(id);
for &c in channels {
out.push(' ');
out.push_str(&channel(c));
}
out.push_str(&alpha_suffix(alpha));
out.push(')');
out
}
pub fn format_hsl(h: f64, s: f64, l: f64, alpha: Option<f64>) -> String {
let mut out = String::with_capacity(24);
write!(
out,
"hsl({} {} {}{})",
channel(h),
channel_pct(s),
channel_pct(l),
alpha_suffix(alpha),
)
.unwrap();
out
}
pub fn format_hwb(h: f64, w: f64, b: f64, alpha: Option<f64>) -> String {
let mut out = String::with_capacity(24);
write!(
out,
"hwb({} {} {}{})",
channel(h),
channel_pct(w),
channel_pct(b),
alpha_suffix(alpha),
)
.unwrap();
out
}
pub fn format_lab_like(name: &str, l: f64, a: f64, b: f64, alpha: Option<f64>) -> String {
let mut out = String::with_capacity(24);
write!(
out,
"{name}({} {} {}{})",
channel(l),
channel(a),
channel(b),
alpha_suffix(alpha),
)
.unwrap();
out
}
pub fn format_lch_like(name: &str, l: f64, c: f64, h: f64, alpha: Option<f64>) -> String {
let mut out = String::with_capacity(24);
write!(
out,
"{name}({} {} {}{})",
channel(l),
channel(c),
channel(h),
alpha_suffix(alpha),
)
.unwrap();
out
}