polished_css/data_type/
ratio.rs

1/// [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/ratio)
2/// [CSSWG](https://drafts.csswg.org/css-values/#ratios)
3#[derive(Clone, Debug, PartialEq)]
4pub struct Ratio {
5    pub a: f64,
6    pub b: Option<f64>,
7}
8
9impl std::fmt::Display for Ratio {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        if let Some(b) = self.b {
12            write!(f, "{}/{}", self.a, b)
13        } else {
14            write!(f, "{}", self.a)
15        }
16    }
17}
18
19impl From<i32> for Ratio {
20    fn from(value: i32) -> Self {
21        Self {
22            a: value.into(),
23            b: None,
24        }
25    }
26}
27impl From<f64> for Ratio {
28    fn from(value: f64) -> Self {
29        Self { a: value, b: None }
30    }
31}
32
33impl From<(i32, i32)> for Ratio {
34    fn from(value: (i32, i32)) -> Self {
35        Self {
36            a: value.0.into(),
37            b: Some(value.1.into()),
38        }
39    }
40}
41impl From<(f64, f64)> for Ratio {
42    fn from(value: (f64, f64)) -> Self {
43        Self {
44            a: value.0,
45            b: Some(value.1),
46        }
47    }
48}
49
50impl From<(i32, Option<i32>)> for Ratio {
51    fn from(value: (i32, Option<i32>)) -> Self {
52        Self {
53            a: value.0.into(),
54            b: value.1.map(std::convert::Into::into),
55        }
56    }
57}
58impl From<(f64, Option<f64>)> for Ratio {
59    fn from(value: (f64, Option<f64>)) -> Self {
60        Self {
61            a: value.0,
62            b: value.1,
63        }
64    }
65}
66
67pub trait RatioStorage: From<Ratio> {
68    #[must_use]
69    fn ratio(value: Ratio) -> Self
70    where
71        Self: Sized + From<Ratio>,
72    {
73        Self::from(value)
74    }
75}
76
77// TODO: Add bounds, cannot be zero
78
79#[cfg(test)]
80mod test {
81    #[test]
82    fn display() {
83        assert_eq!(super::Ratio::from((1, None)).to_string(), "1");
84        assert_eq!(super::Ratio::from(1).to_string(), "1");
85        assert_eq!(super::Ratio::from((4, Some(3))).to_string(), "4/3");
86        assert_eq!(super::Ratio::from((16.0, Some(9.0))).to_string(), "16/9");
87        assert_eq!(
88            super::Ratio::from((66.6, Some(133.7))).to_string(),
89            "66.6/133.7"
90        );
91    }
92}