Skip to main content

photon_ui/layout/
constraint.rs

1use std::fmt;
2
3/// A size constraint for layout elements.
4#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
5pub enum Constraint {
6    Min(u16),
7    Max(u16),
8    Length(u16),
9    Percentage(u16),
10    Ratio(u32, u32),
11    Fill(u16),
12}
13
14impl Constraint {
15    pub fn from_lengths<T>(lengths: T) -> Vec<Self>
16    where
17        T: IntoIterator<Item = u16>, {
18        lengths.into_iter().map(Self::Length).collect()
19    }
20
21    pub fn from_ratios<T>(ratios: T) -> Vec<Self>
22    where
23        T: IntoIterator<Item = (u32, u32)>, {
24        ratios.into_iter().map(|(n, d)| Self::Ratio(n, d)).collect()
25    }
26
27    pub fn from_percentages<T>(percentages: T) -> Vec<Self>
28    where
29        T: IntoIterator<Item = u16>, {
30        percentages.into_iter().map(Self::Percentage).collect()
31    }
32
33    pub fn from_mins<T>(mins: T) -> Vec<Self>
34    where
35        T: IntoIterator<Item = u16>, {
36        mins.into_iter().map(Self::Min).collect()
37    }
38
39    pub fn from_maxes<T>(maxes: T) -> Vec<Self>
40    where
41        T: IntoIterator<Item = u16>, {
42        maxes.into_iter().map(Self::Max).collect()
43    }
44
45    pub fn from_fills<T>(fills: T) -> Vec<Self>
46    where
47        T: IntoIterator<Item = u16>, {
48        fills.into_iter().map(Self::Fill).collect()
49    }
50}
51
52impl From<u16> for Constraint {
53    fn from(length: u16) -> Self {
54        Self::Length(length)
55    }
56}
57
58impl From<&Self> for Constraint {
59    fn from(constraint: &Self) -> Self {
60        *constraint
61    }
62}
63
64impl AsRef<Self> for Constraint {
65    fn as_ref(&self) -> &Self {
66        self
67    }
68}
69
70impl Default for Constraint {
71    fn default() -> Self {
72        Self::Percentage(100)
73    }
74}
75
76impl fmt::Display for Constraint {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        match self {
79            | Self::Percentage(p) => write!(f, "Percentage({p})"),
80            | Self::Ratio(n, d) => write!(f, "Ratio({n}, {d})"),
81            | Self::Length(l) => write!(f, "Length({l})"),
82            | Self::Fill(l) => write!(f, "Fill({l})"),
83            | Self::Max(m) => write!(f, "Max({m})"),
84            | Self::Min(m) => write!(f, "Min({m})"),
85        }
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn constraint_default() {
95        assert_eq!(Constraint::default(), Constraint::Percentage(100));
96    }
97
98    #[test]
99    fn constraint_from_u16() {
100        let c: Constraint = 10.into();
101        assert_eq!(c, Constraint::Length(10));
102    }
103
104    #[test]
105    fn constraint_from_ref() {
106        let c = Constraint::Length(5);
107        assert_eq!(Constraint::from(&c), c);
108    }
109
110    #[test]
111    fn constraint_as_ref() {
112        let c = Constraint::Length(5);
113        assert_eq!(c.as_ref(), &Constraint::Length(5));
114    }
115
116    #[test]
117    fn constraint_display() {
118        assert_eq!(Constraint::Percentage(50).to_string(), "Percentage(50)");
119        assert_eq!(Constraint::Ratio(1, 2).to_string(), "Ratio(1, 2)");
120        assert_eq!(Constraint::Length(10).to_string(), "Length(10)");
121        assert_eq!(Constraint::Fill(1).to_string(), "Fill(1)");
122        assert_eq!(Constraint::Max(20).to_string(), "Max(20)");
123        assert_eq!(Constraint::Min(5).to_string(), "Min(5)");
124    }
125
126    #[test]
127    fn constraint_from_lengths() {
128        let c = Constraint::from_lengths([1, 2, 3]);
129        assert_eq!(
130            c,
131            vec![
132                Constraint::Length(1),
133                Constraint::Length(2),
134                Constraint::Length(3)
135            ]
136        );
137    }
138
139    #[test]
140    fn constraint_from_ratios() {
141        let c = Constraint::from_ratios([(1, 4), (1, 2)]);
142        assert_eq!(c, vec![Constraint::Ratio(1, 4), Constraint::Ratio(1, 2)]);
143    }
144
145    #[test]
146    fn constraint_from_percentages() {
147        let c = Constraint::from_percentages([25, 50]);
148        assert_eq!(
149            c,
150            vec![Constraint::Percentage(25), Constraint::Percentage(50)]
151        );
152    }
153
154    #[test]
155    fn constraint_from_mins() {
156        let c = Constraint::from_mins([1, 2]);
157        assert_eq!(c, vec![Constraint::Min(1), Constraint::Min(2)]);
158    }
159
160    #[test]
161    fn constraint_from_maxes() {
162        let c = Constraint::from_maxes([10, 20]);
163        assert_eq!(c, vec![Constraint::Max(10), Constraint::Max(20)]);
164    }
165
166    #[test]
167    fn constraint_from_fills() {
168        let c = Constraint::from_fills([1, 2, 3]);
169        assert_eq!(
170            c,
171            vec![
172                Constraint::Fill(1),
173                Constraint::Fill(2),
174                Constraint::Fill(3)
175            ]
176        );
177    }
178}