1#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord, Hash)]
18pub struct Border<T> {
19 pub top: Option<T>,
21 pub bottom: Option<T>,
23 pub left: Option<T>,
25 pub right: Option<T>,
27 pub left_top_corner: Option<T>,
29 pub left_bottom_corner: Option<T>,
31 pub right_top_corner: Option<T>,
33 pub right_bottom_corner: Option<T>,
35}
36
37impl<T> Border<T> {
38 #[allow(clippy::too_many_arguments)]
40 pub const fn new(
41 top: Option<T>,
42 bottom: Option<T>,
43 left: Option<T>,
44 right: Option<T>,
45 left_top_corner: Option<T>,
46 left_bottom_corner: Option<T>,
47 right_top_corner: Option<T>,
48 right_bottom_corner: Option<T>,
49 ) -> Self {
50 Self {
51 top,
52 bottom,
53 left,
54 right,
55 left_top_corner,
56 left_bottom_corner,
57 right_top_corner,
58 right_bottom_corner,
59 }
60 }
61
62 #[allow(clippy::too_many_arguments)]
64 pub const fn full(
65 top: T,
66 bottom: T,
67 left: T,
68 right: T,
69 top_left: T,
70 top_right: T,
71 bottom_left: T,
72 bottom_right: T,
73 ) -> Self {
74 Self::new(
75 Some(top),
76 Some(bottom),
77 Some(left),
78 Some(right),
79 Some(top_left),
80 Some(bottom_left),
81 Some(top_right),
82 Some(bottom_right),
83 )
84 }
85
86 pub const fn empty() -> Self {
88 Self::new(None, None, None, None, None, None, None, None)
89 }
90
91 pub const fn is_empty(&self) -> bool {
93 self.top.is_none()
94 && self.left_top_corner.is_none()
95 && self.right_top_corner.is_none()
96 && self.bottom.is_none()
97 && self.left_bottom_corner.is_none()
98 && self.left_top_corner.is_none()
99 && self.left.is_none()
100 && self.right.is_none()
101 }
102
103 pub fn is_same(&self) -> bool
105 where
106 T: PartialEq,
107 {
108 self.top == self.bottom
109 && self.top == self.left
110 && self.top == self.right
111 && self.top == self.left_top_corner
112 && self.top == self.right_top_corner
113 && self.top == self.left_bottom_corner
114 && self.top == self.right_bottom_corner
115 }
116
117 pub const fn has_top(&self) -> bool {
119 self.top.is_some() || self.left_top_corner.is_some() || self.right_top_corner.is_some()
120 }
121
122 pub const fn has_bottom(&self) -> bool {
124 self.bottom.is_some()
125 || self.left_bottom_corner.is_some()
126 || self.right_bottom_corner.is_some()
127 }
128
129 pub const fn has_left(&self) -> bool {
131 self.left.is_some() || self.left_top_corner.is_some() || self.left_bottom_corner.is_some()
132 }
133
134 pub const fn has_right(&self) -> bool {
136 self.right.is_some()
137 || self.right_top_corner.is_some()
138 || self.right_bottom_corner.is_some()
139 }
140
141 pub fn map<F, T1>(self, f: F) -> Border<T1>
143 where
144 F: Fn(T) -> T1,
145 {
146 Border {
147 top: self.top.map(&f),
148 bottom: self.bottom.map(&f),
149 left: self.left.map(&f),
150 right: self.right.map(&f),
151 left_top_corner: self.left_top_corner.map(&f),
152 left_bottom_corner: self.left_bottom_corner.map(&f),
153 right_top_corner: self.right_top_corner.map(&f),
154 right_bottom_corner: self.right_bottom_corner.map(&f),
155 }
156 }
157}
158
159impl<T: Copy> Border<T> {
160 pub const fn filled(c: T) -> Self {
164 Self::full(c, c, c, c, c, c, c, c)
165 }
166}
167
168impl<T: Copy> Border<&T> {
169 pub fn copied(&self) -> Border<T> {
171 Border {
172 top: self.top.copied(),
173 bottom: self.bottom.copied(),
174 left: self.left.copied(),
175 right: self.right.copied(),
176 left_bottom_corner: self.left_bottom_corner.copied(),
177 left_top_corner: self.left_top_corner.copied(),
178 right_bottom_corner: self.right_bottom_corner.copied(),
179 right_top_corner: self.right_top_corner.copied(),
180 }
181 }
182}
183
184impl<T: Clone> Border<&T> {
185 pub fn cloned(&self) -> Border<T> {
187 Border {
188 top: self.top.cloned(),
189 bottom: self.bottom.cloned(),
190 left: self.left.cloned(),
191 right: self.right.cloned(),
192 left_bottom_corner: self.left_bottom_corner.cloned(),
193 left_top_corner: self.left_top_corner.cloned(),
194 right_bottom_corner: self.right_bottom_corner.cloned(),
195 right_top_corner: self.right_top_corner.cloned(),
196 }
197 }
198}
199
200impl<T> Border<T> {
201 pub fn convert<B>(self) -> Border<B>
203 where
204 B: From<T>,
205 {
206 macro_rules! conv_opt {
207 ($opt:expr) => {
208 match $opt {
209 Some(opt) => Some(B::from(opt)),
210 None => None,
211 }
212 };
213 }
214
215 Border {
216 top: conv_opt!(self.top),
217 bottom: conv_opt!(self.bottom),
218 left: conv_opt!(self.left),
219 right: conv_opt!(self.right),
220 left_bottom_corner: conv_opt!(self.left_bottom_corner),
221 left_top_corner: conv_opt!(self.left_top_corner),
222 right_bottom_corner: conv_opt!(self.right_bottom_corner),
223 right_top_corner: conv_opt!(self.right_top_corner),
224 }
225 }
226}