use crate::parser::CssProperty;
fn size_value(key: &str) -> Option<&'static str> {
match key {
"0" => Some("0px"),
"px" => Some("1px"),
"0.5" => Some("0.125rem"),
"1" => Some("0.25rem"),
"2" => Some("0.5rem"),
"3" => Some("0.75rem"),
"4" => Some("1rem"),
"5" => Some("1.25rem"),
"6" => Some("1.5rem"),
"8" => Some("2rem"),
"10" => Some("2.5rem"),
"12" => Some("3rem"),
"14" => Some("3.5rem"),
"16" => Some("4rem"),
"20" => Some("5rem"),
"24" => Some("6rem"),
"28" => Some("7rem"),
"32" => Some("8rem"),
"36" => Some("9rem"),
"40" => Some("10rem"),
"44" => Some("11rem"),
"48" => Some("12rem"),
"52" => Some("13rem"),
"56" => Some("14rem"),
"60" => Some("15rem"),
"64" => Some("16rem"),
"72" => Some("18rem"),
"80" => Some("20rem"),
"96" => Some("24rem"),
"1/2" => Some("50%"),
"1/3" => Some("33.333333%"),
"2/3" => Some("66.666667%"),
"1/4" => Some("25%"),
"2/4" => Some("50%"),
"3/4" => Some("75%"),
"1/5" => Some("20%"),
"2/5" => Some("40%"),
"3/5" => Some("60%"),
"4/5" => Some("80%"),
"1/6" => Some("16.666667%"),
"5/6" => Some("83.333333%"),
"1/12" => Some("8.333333%"),
"full" => Some("100%"),
"screen" => Some("100vw"),
"svw" => Some("100svw"),
"lvw" => Some("100lvw"),
"dvw" => Some("100dvw"),
"min" => Some("min-content"),
"max" => Some("max-content"),
"fit" => Some("fit-content"),
"auto" => Some("auto"),
_ => None,
}
}
fn height_value(key: &str) -> Option<&'static str> {
match key {
"screen" => Some("100vh"),
"svh" => Some("100svh"),
"lvh" => Some("100lvh"),
"dvh" => Some("100dvh"),
_ => size_value(key),
}
}
fn max_width_value(key: &str) -> Option<&'static str> {
match key {
"0" => Some("0rem"),
"none" => Some("none"),
"xs" => Some("20rem"),
"sm" => Some("24rem"),
"md" => Some("28rem"),
"lg" => Some("32rem"),
"xl" => Some("36rem"),
"2xl" => Some("42rem"),
"3xl" => Some("48rem"),
"4xl" => Some("56rem"),
"5xl" => Some("64rem"),
"6xl" => Some("72rem"),
"7xl" => Some("80rem"),
"full" => Some("100%"),
"min" => Some("min-content"),
"max" => Some("max-content"),
"fit" => Some("fit-content"),
"prose" => Some("65ch"),
"screen-sm" => Some("640px"),
"screen-md" => Some("768px"),
"screen-lg" => Some("1024px"),
"screen-xl" => Some("1280px"),
"screen-2xl" => Some("1536px"),
_ => None,
}
}
pub fn parse(utility: &str) -> Option<Vec<CssProperty>> {
if let Some(val) = utility.strip_prefix("w-") {
let value = size_value(val)?;
return Some(vec![CssProperty::new("width", value)]);
}
if let Some(val) = utility.strip_prefix("h-") {
let value = height_value(val)?;
return Some(vec![CssProperty::new("height", value)]);
}
if let Some(val) = utility.strip_prefix("min-w-") {
let value = size_value(val)?;
return Some(vec![CssProperty::new("min-width", value)]);
}
if let Some(val) = utility.strip_prefix("min-h-") {
let value = height_value(val)?;
return Some(vec![CssProperty::new("min-height", value)]);
}
if let Some(val) = utility.strip_prefix("max-w-") {
let value = max_width_value(val)?;
return Some(vec![CssProperty::new("max-width", value)]);
}
if let Some(val) = utility.strip_prefix("max-h-") {
let value = height_value(val)?;
return Some(vec![CssProperty::new("max-height", value)]);
}
if let Some(val) = utility.strip_prefix("size-") {
let value = size_value(val)?;
return Some(vec![
CssProperty::new("width", value),
CssProperty::new("height", value),
]);
}
None
}
pub fn parse_arbitrary(prefix: &str, value: &str) -> Option<Vec<CssProperty>> {
let property = match prefix {
"w" => "width",
"h" => "height",
"min-w" => "min-width",
"min-h" => "min-height",
"max-w" => "max-width",
"max-h" => "max-height",
_ => return None,
};
Some(vec![CssProperty::new(property, value)])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_width() {
let props = parse("w-full").unwrap();
assert_eq!(props[0].property, "width");
assert_eq!(props[0].value, "100%");
}
#[test]
fn test_height_screen() {
let props = parse("h-screen").unwrap();
assert_eq!(props[0].property, "height");
assert_eq!(props[0].value, "100vh");
}
#[test]
fn test_max_width() {
let props = parse("max-w-lg").unwrap();
assert_eq!(props[0].property, "max-width");
assert_eq!(props[0].value, "32rem");
}
#[test]
fn test_size() {
let props = parse("size-4").unwrap();
assert_eq!(props.len(), 2);
assert_eq!(props[0].property, "width");
assert_eq!(props[1].property, "height");
}
}