use core::fmt;
use crate::to_css::{write_number, ToCss};
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Length {
Px(f32),
Rpx(f32),
Ppx(f32),
Em(f32),
Rem(f32),
Vh(f32),
Vw(f32),
Zero,
}
impl Length {
pub fn is_zero(self) -> bool {
match self {
Length::Zero => true,
Length::Px(v)
| Length::Rpx(v)
| Length::Ppx(v)
| Length::Em(v)
| Length::Rem(v)
| Length::Vh(v)
| Length::Vw(v) => v == 0.0,
}
}
}
impl ToCss for Length {
fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
let (v, unit) = match *self {
Length::Zero => return dest.write_char('0'),
Length::Px(v) => (v, "px"),
Length::Rpx(v) => (v, "rpx"),
Length::Ppx(v) => (v, "ppx"),
Length::Em(v) => (v, "em"),
Length::Rem(v) => (v, "rem"),
Length::Vh(v) => (v, "vh"),
Length::Vw(v) => (v, "vw"),
};
write_number(dest, v)?;
dest.write_str(unit)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn each_unit_serializes() {
assert_eq!(Length::Px(8.0).to_css_string(), "8px");
assert_eq!(Length::Rpx(750.0).to_css_string(), "750rpx");
assert_eq!(Length::Ppx(2.0).to_css_string(), "2ppx");
assert_eq!(Length::Em(1.5).to_css_string(), "1.5em");
assert_eq!(Length::Rem(1.0).to_css_string(), "1rem");
assert_eq!(Length::Vh(50.0).to_css_string(), "50vh");
assert_eq!(Length::Vw(100.0).to_css_string(), "100vw");
}
#[test]
fn zero_serializes_unitless() {
assert_eq!(Length::Zero.to_css_string(), "0");
}
#[test]
fn fractional_values_keep_decimal() {
assert_eq!(Length::Px(0.5).to_css_string(), "0.5px");
assert_eq!(Length::Px(-1.25).to_css_string(), "-1.25px");
}
#[test]
fn is_zero_detects_all_variants() {
assert!(Length::Zero.is_zero());
assert!(Length::Px(0.0).is_zero());
assert!(Length::Vh(0.0).is_zero());
assert!(!Length::Px(0.1).is_zero());
assert!(!Length::Rpx(1.0).is_zero());
}
}