1#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum Position {
6 #[default]
8 Top,
9 Bottom,
11 Center,
13 Left,
15 Right,
17}
18
19impl Position {
20 pub fn factor(&self) -> f64 {
22 match self {
23 Position::Top | Position::Left => 0.0,
24 Position::Center => 0.5,
25 Position::Bottom | Position::Right => 1.0,
26 }
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
32pub struct Sides<T> {
33 pub top: T,
34 pub right: T,
35 pub bottom: T,
36 pub left: T,
37}
38
39impl<T: Copy> Sides<T> {
40 pub const fn all(value: T) -> Self {
42 Self {
43 top: value,
44 right: value,
45 bottom: value,
46 left: value,
47 }
48 }
49
50 pub const fn new(top: T, right: T, bottom: T, left: T) -> Self {
52 Self {
53 top,
54 right,
55 bottom,
56 left,
57 }
58 }
59}
60
61impl<T: Copy + Default> Sides<T> {
62 pub fn zero() -> Self
64 where
65 T: Default,
66 {
67 Self::default()
68 }
69}
70
71impl<T: Copy> From<T> for Sides<T> {
74 fn from(all: T) -> Self {
76 Self::all(all)
77 }
78}
79
80impl<T: Copy> From<(T, T)> for Sides<T> {
81 fn from((vertical, horizontal): (T, T)) -> Self {
83 Self {
84 top: vertical,
85 right: horizontal,
86 bottom: vertical,
87 left: horizontal,
88 }
89 }
90}
91
92impl<T: Copy> From<(T, T, T)> for Sides<T> {
93 fn from((top, horizontal, bottom): (T, T, T)) -> Self {
95 Self {
96 top,
97 right: horizontal,
98 bottom,
99 left: horizontal,
100 }
101 }
102}
103
104impl<T: Copy> From<(T, T, T, T)> for Sides<T> {
105 fn from((top, right, bottom, left): (T, T, T, T)) -> Self {
107 Self {
108 top,
109 right,
110 bottom,
111 left,
112 }
113 }
114}
115
116impl<T: Copy> From<[T; 1]> for Sides<T> {
117 fn from([all]: [T; 1]) -> Self {
118 Self::all(all)
119 }
120}
121
122impl<T: Copy> From<[T; 2]> for Sides<T> {
123 fn from([vertical, horizontal]: [T; 2]) -> Self {
124 Self {
125 top: vertical,
126 right: horizontal,
127 bottom: vertical,
128 left: horizontal,
129 }
130 }
131}
132
133impl<T: Copy> From<[T; 4]> for Sides<T> {
134 fn from([top, right, bottom, left]: [T; 4]) -> Self {
135 Self {
136 top,
137 right,
138 bottom,
139 left,
140 }
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_position_factor() {
150 let eps = f64::EPSILON;
151 assert!((Position::Top.factor() - 0.0).abs() < eps);
152 assert!((Position::Center.factor() - 0.5).abs() < eps);
153 assert!((Position::Bottom.factor() - 1.0).abs() < eps);
154 }
155
156 #[test]
157 fn test_sides_from_single() {
158 let s: Sides<u16> = 5.into();
159 assert_eq!(s.top, 5);
160 assert_eq!(s.right, 5);
161 assert_eq!(s.bottom, 5);
162 assert_eq!(s.left, 5);
163 }
164
165 #[test]
166 fn test_sides_from_tuple2() {
167 let s: Sides<u16> = (5, 10).into();
168 assert_eq!(s.top, 5);
169 assert_eq!(s.right, 10);
170 assert_eq!(s.bottom, 5);
171 assert_eq!(s.left, 10);
172 }
173
174 #[test]
175 fn test_sides_from_tuple4() {
176 let s: Sides<u16> = (1, 2, 3, 4).into();
177 assert_eq!(s.top, 1);
178 assert_eq!(s.right, 2);
179 assert_eq!(s.bottom, 3);
180 assert_eq!(s.left, 4);
181 }
182}