orbtk_utils/
thickness.rs

1use crate::Value;
2
3/// Used to describes a thickness e.g a border thickness.
4#[derive(Copy, Clone, Default, Debug, PartialEq)]
5pub struct Thickness {
6    /// Left of thickness.
7    pub left: f64,
8
9    /// Top of thickness.
10    pub top: f64,
11
12    /// Right of thickness.
13    pub right: f64,
14
15    /// Bottom of thickness.
16    pub bottom: f64,
17}
18
19impl Thickness {
20    /// Create a new thickness with the given parameters.
21    pub fn new(left: f64, top: f64, right: f64, bottom: f64) -> Self {
22        Thickness {
23            left,
24            top,
25            right,
26            bottom,
27        }
28    }
29
30    /// Gets left.
31    pub fn left(&self) -> f64 {
32        self.left
33    }
34
35    /// Sets left.
36    pub fn set_left(&mut self, left: f64) {
37        self.left = left;
38    }
39
40    /// Gets top.
41    pub fn top(&self) -> f64 {
42        self.top
43    }
44
45    /// Sets top.
46    pub fn set_top(&mut self, top: f64) {
47        self.top = top;
48    }
49
50    /// Gets right.
51    pub fn right(&self) -> f64 {
52        self.right
53    }
54
55    /// Sets right.
56    pub fn set_right(&mut self, right: f64) {
57        self.right = right;
58    }
59
60    /// Gets bottom.
61    pub fn bottom(&self) -> f64 {
62        self.bottom
63    }
64
65    /// Sets bottom.
66    pub fn set_bottom(&mut self, bottom: f64) {
67        self.bottom = bottom;
68    }
69
70    /// Gets thickness.
71    pub fn thickness(&self) -> Thickness {
72        *self
73    }
74
75    /// Sets thickness.
76    pub fn set_thickness<T: Into<Thickness>>(&mut self, thickness: T) {
77        let other = thickness.into();
78
79        self.set_left(other.left());
80        self.set_top(other.top());
81        self.set_right(other.right());
82        self.set_bottom(other.bottom());
83    }
84}
85
86// --- Trait implementations ---
87
88impl From<(i32, i32, i32, i32)> for Thickness {
89    fn from(t: (i32, i32, i32, i32)) -> Self {
90        Thickness::new(t.0 as f64, t.1 as f64, t.2 as f64, t.3 as f64)
91    }
92}
93
94impl From<(i32, i32)> for Thickness {
95    fn from(t: (i32, i32)) -> Self {
96        Thickness::new(t.0 as f64, t.1 as f64, t.0 as f64, t.1 as f64)
97    }
98}
99
100impl From<i32> for Thickness {
101    fn from(t: i32) -> Self {
102        Thickness::new(t as f64, t as f64, t as f64, t as f64)
103    }
104}
105
106impl From<(f64, f64, f64, f64)> for Thickness {
107    fn from(t: (f64, f64, f64, f64)) -> Self {
108        Thickness::new(t.0, t.1, t.2, t.3)
109    }
110}
111
112impl From<(f64, f64)> for Thickness {
113    fn from(t: (f64, f64)) -> Self {
114        Thickness::new(t.0, t.1, t.0, t.1)
115    }
116}
117
118impl From<f64> for Thickness {
119    fn from(t: f64) -> Self {
120        Thickness::new(t, t, t, t)
121    }
122}
123
124impl From<Value> for Thickness {
125    fn from(v: Value) -> Self {
126        match v.0 {
127            ron::Value::Number(value) => Thickness::from(value.into_f64()),
128            ron::Value::Map(map) => {
129                let mut left = 0.0;
130                let mut top = 0.0;
131                let mut right = 0.0;
132                let mut bottom = 0.0;
133
134                for (key, value) in map.iter() {
135                    if let Ok(key) = key.clone().into_rust::<String>() {
136                        let value = if let Ok(value) = value.clone().into_rust::<f64>() {
137                            value
138                        } else {
139                            0.0
140                        };
141
142                        if key.as_str().eq("left") {
143                            left = value;
144                        }
145
146                        if key.as_str().eq("top") {
147                            top = value;
148                        }
149
150                        if key.as_str().eq("right") {
151                            right = value;
152                        }
153
154                        if key.as_str().eq("bottom") {
155                            bottom = value;
156                        }
157                    }
158                }
159
160                Thickness::from((left, top, right, bottom))
161            }
162            _ => Thickness::default(),
163        }
164    }
165}
166
167#[cfg(test)]
168mod tests {
169    use crate::prelude::*;
170
171    #[test]
172    fn test_new() {
173        let rect = Thickness::new(5.0, 10.0, 20.0, 30.0);
174
175        assert!(crate::f64_cmp(rect.left, 5.0));
176        assert!(crate::f64_cmp(rect.top, 10.0));
177        assert!(crate::f64_cmp(rect.right, 20.0));
178        assert!(crate::f64_cmp(rect.bottom, 30.0));
179    }
180
181    #[test]
182    fn test_into() {
183        let thickness: Thickness = (10.0, 12.0, 13.0, 14.0).into();
184
185        assert!(crate::f64_cmp(thickness.left, 10.0));
186        assert!(crate::f64_cmp(thickness.top, 12.0));
187        assert!(crate::f64_cmp(thickness.right, 13.0));
188        assert!(crate::f64_cmp(thickness.bottom, 14.0));
189
190        let thickness: Thickness = 10.0.into();
191
192        assert!(crate::f64_cmp(thickness.left, 10.0));
193        assert!(crate::f64_cmp(thickness.top, 10.0));
194        assert!(crate::f64_cmp(thickness.right, 10.0));
195        assert!(crate::f64_cmp(thickness.bottom, 10.0));
196    }
197}