encre_css/utils/
spacing.rs

1//! Spacing utility functions.
2use std::borrow::Cow;
3
4/// Returns whether the modifier is matching a builtin spacing value. The builtin spacing values are:
5///
6/// - `px`;
7/// - Any float ([`f32`]);
8/// - Any fraction (e.g `9/12`) consisting of a [`usize`], a slash and another [`usize`].
9pub fn is_matching_builtin_spacing(value: &str) -> bool {
10    value == "px"
11        || value.parse::<f64>().is_ok()
12        || value
13            .split_once('/')
14            .is_some_and(|(a, b)| a.parse::<usize>().is_ok() && b.parse::<usize>().is_ok())
15}
16
17/// Get a spacing value from a modifier.
18///
19/// Spacing values don't follow Tailwind's philosophy of limiting possible values and are closer
20/// to [Windi CSS](https://windicss.org/features/value-auto-infer.html#numbers). They are
21/// however perfectly compatible with Tailwind's values.
22pub fn get(value: &str, is_negative: bool) -> Option<Cow<'_, str>> {
23    if value == "px" {
24        if is_negative {
25            Some(Cow::from("-1px"))
26        } else {
27            Some(Cow::from("1px"))
28        }
29    } else if value == "0" {
30        Some(Cow::from("0px"))
31    } else if let Some((a, b)) = value.split_once('/') {
32        // Fractions
33        let a = a.parse::<usize>().ok()?;
34        let b = b.parse::<usize>().ok()?;
35
36        #[allow(clippy::cast_precision_loss)]
37        if is_negative {
38            Some(Cow::from(format!(
39                "{}%",
40                (1_000_000. * 100. * (-(a as f64) / b as f64)).round() / 1_000_000.
41            )))
42        } else {
43            Some(Cow::from(format!(
44                "{}%",
45                (1_000_000. * 100. * (a as f64 / b as f64)).round() / 1_000_000.
46            )))
47        }
48    } else {
49        // Floats
50        let value = if is_negative {
51            -value.parse::<f64>().ok()? / 4.
52        } else {
53            value.parse::<f64>().ok()? / 4.
54        };
55
56        Some(Cow::from(format!("{value}rem")))
57    }
58}