1use crate::Value;
2
3#[derive(Copy, Clone, Default, Debug, PartialEq)]
5pub struct Thickness {
6 pub left: f64,
8
9 pub top: f64,
11
12 pub right: f64,
14
15 pub bottom: f64,
17}
18
19impl Thickness {
20 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 pub fn left(&self) -> f64 {
32 self.left
33 }
34
35 pub fn set_left(&mut self, left: f64) {
37 self.left = left;
38 }
39
40 pub fn top(&self) -> f64 {
42 self.top
43 }
44
45 pub fn set_top(&mut self, top: f64) {
47 self.top = top;
48 }
49
50 pub fn right(&self) -> f64 {
52 self.right
53 }
54
55 pub fn set_right(&mut self, right: f64) {
57 self.right = right;
58 }
59
60 pub fn bottom(&self) -> f64 {
62 self.bottom
63 }
64
65 pub fn set_bottom(&mut self, bottom: f64) {
67 self.bottom = bottom;
68 }
69
70 pub fn thickness(&self) -> Thickness {
72 *self
73 }
74
75 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
86impl 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}