Skip to main content

polyhorn_style/
dimension.rs

1use super::keywords::Auto;
2use std::fmt::{Debug, Display, Formatter, Result};
3
4#[derive(Copy, Clone, PartialEq)]
5pub enum Dimension {
6    Undefined,
7    Auto,
8    Pixels(f32),
9    Percent(f32),
10}
11
12impl Dimension {
13    pub fn auto() -> Dimension {
14        Dimension::Auto
15    }
16
17    pub fn unwrap_or(self, dimension: Dimension) -> Dimension {
18        match self {
19            Dimension::Auto | Dimension::Undefined => dimension,
20            _ => self,
21        }
22    }
23}
24
25impl Debug for Dimension {
26    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
27        match self {
28            Dimension::Undefined => f.write_str("undefined"),
29            Dimension::Auto => f.write_str("auto"),
30            Dimension::Pixels(pixels) => f.write_fmt(format_args!("{}px", pixels)),
31            Dimension::Percent(percent) => f.write_fmt(format_args!("{}%", percent * 100.0)),
32        }
33    }
34}
35
36impl Display for Dimension {
37    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
38        Debug::fmt(self, f)
39    }
40}
41
42impl From<Auto> for Dimension {
43    fn from(_: Auto) -> Self {
44        Dimension::Auto
45    }
46}
47
48impl Default for Dimension {
49    fn default() -> Self {
50        Dimension::Undefined
51    }
52}
53
54/// This is a trait that is implemented by integer and float types to make it
55/// more ergonomic to work with literals (e.g.
56/// `5.px() = Dimension::pixels(5.0)`).
57pub trait IntoDimension {
58    fn px(self) -> Dimension;
59    fn pct(self) -> Dimension;
60}
61
62impl IntoDimension for isize {
63    fn px(self) -> Dimension {
64        Dimension::Pixels(self as f32)
65    }
66
67    fn pct(self) -> Dimension {
68        Dimension::Percent((self as f32) / 100.0)
69    }
70}
71
72impl IntoDimension for f32 {
73    fn px(self) -> Dimension {
74        Dimension::Pixels(self)
75    }
76
77    fn pct(self) -> Dimension {
78        Dimension::Percent(self / 100.0)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn test_display() {
88        assert_eq!(format!("{}", 2.px()), "2px");
89        assert_eq!(format!("{}", 2.5.px()), "2.5px");
90    }
91}