tailwind_css_fixes/systems/units/length_only/
mod.rs1use super::*;
2
3mod traits;
4
5#[derive(Clone, Debug)]
6pub enum UnitValue {
7 Number { n: f32, is_negative: bool },
8 Length(LengthUnit),
9 Keyword(String),
10 Arbitrary(TailwindArbitrary),
11}
12
13impl Display for UnitValue {
14 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
15 match self {
16 Self::Number { n, .. } => write!(f, "{}", n.abs()),
17 Self::Length(n) => write!(f, "{}", n),
18 Self::Keyword(s) => write!(f, "{}", s),
19 Self::Arbitrary(s) => write!(f, "{}", s),
20 }
21 }
22}
23
24impl UnitValue {
26 pub fn px(x: f32) -> Self {
27 Self::Length(LengthUnit::px(x))
28 }
29 pub fn ratio(a: u32, b: u32) -> Self {
30 Self::Length(LengthUnit::ratio(a, b))
31 }
32 pub fn get_properties(&self, number: impl FnOnce(&f32) -> String) -> String {
33 match self {
34 Self::Number { n, .. } => number(n),
35 Self::Length(n) => n.get_properties(),
36 Self::Keyword(s) => s.to_string(),
37 Self::Arbitrary(s) => s.get_properties(),
38 }
39 }
40 pub fn get_properties_rem(&self) -> String {
41 self.get_properties(|f| format!("{}rem", f / 4.0))
42 }
43 pub fn write_negative(&self, f: &mut Formatter) -> std::fmt::Result {
44 match is_negative(self) {
45 true => write!(f, "-"),
46 false => write!(f, ""),
47 }
48 }
49 pub fn write_class(&self, f: &mut Formatter, before: &str) -> std::fmt::Result {
50 write!(f, "{}{}", before, self)
51 }
52}
53
54pub fn is_negative(value: &UnitValue) -> bool {
55 match *value {
56 UnitValue::Number { n, is_negative } if is_negative => n < 0.0,
57 _ => false,
58 }
59}
60
61impl UnitValue {
62 pub fn negative_parser(
63 id: &'static str,
64 check_valid: impl Fn(&str) -> bool,
65 is_length: bool,
66 is_integer: bool,
67 allow_fraction: bool,
68 ) -> impl Fn(&[&str], &TailwindArbitrary, Negative) -> Result<Self> {
69 move |pattern: &[&str], arbitrary: &TailwindArbitrary, negative: Negative| {
70 let kind = match pattern {
71 [] => Self::parse_arbitrary(arbitrary)?,
72 [s] if check_valid(s) => Self::Keyword(s.to_string()),
73 [n] => Self::parse_number(n, negative, is_length, is_integer, allow_fraction)?,
74 _ => {
75 let msg = format!("Unknown {} instructions: {}", id, pattern.join("-"));
76 return Err(TailwindError::syntax_error(msg));
77 },
78 };
79 Ok(kind)
80 }
81 }
82 pub fn positive_parser(
83 id: &'static str,
84 check_valid: impl Fn(&str) -> bool,
85 is_length: bool,
86 is_integer: bool,
87 allow_fraction: bool,
88 ) -> impl Fn(&[&str], &TailwindArbitrary) -> Result<Self> {
89 move |pattern: &[&str], arbitrary: &TailwindArbitrary| {
90 let kind = match pattern {
91 [] => Self::parse_arbitrary(arbitrary)?,
92 [s] if check_valid(s) => Self::Keyword(s.to_string()),
93 [n] => Self::parse_number(n, Negative::from(false), is_length, is_integer, allow_fraction)?,
94 _ => {
95 let msg = format!("Unknown {} instructions: {}", id, pattern.join("-"));
96 return Err(TailwindError::syntax_error(msg));
97 },
98 };
99 Ok(kind)
100 }
101 }
102 pub fn parse_arbitrary(arbitrary: &TailwindArbitrary) -> Result<Self> {
103 Ok(Self::Arbitrary(TailwindArbitrary::new(arbitrary)?))
104 }
105 pub fn parse_number(n: &str, negative: Negative, is_length: bool, is_integer: bool, can_be_fraction: bool) -> Result<Self> {
106 let a = TailwindArbitrary::from(n);
107 match is_length {
108 true => Self::maybe_length(&a, can_be_fraction),
109 false => Self::maybe_angle(&a),
110 }
111 .or_else(|_| Self::maybe_number(&a, negative, is_integer))
112 }
113 fn maybe_number(arbitrary: &TailwindArbitrary, negative: Negative, is_integer: bool) -> Result<Self> {
114 let mut n = match is_integer {
115 true => arbitrary.as_integer()? as f32,
116 false => arbitrary.as_float()?,
117 };
118 if negative.0 {
119 n = -n
120 };
121 Ok(Self::Number { n, is_negative: negative.0 })
122 }
123 fn maybe_length(arbitrary: &TailwindArbitrary, allow_fraction: bool) -> Result<Self> {
124 let n = match allow_fraction {
125 true => arbitrary.as_length_or_fraction(),
126 false => arbitrary.as_length(),
127 }?;
128 Ok(Self::Length(n))
129 }
130 fn maybe_angle(arbitrary: &TailwindArbitrary) -> Result<Self> {
131 Ok(Self::Length(arbitrary.as_angle()?))
132 }
133}