terminal_draw/
geometry.rs1
2
3pub trait Int: Sized {
4 fn to_u16(&self) -> u16;
5 fn from_u16(u16: u16) -> Self;
6}
7
8impl Int for u16 {
9 fn to_u16(&self) -> u16 {
10 *self
11 }
12 fn from_u16(u16: u16) -> Self {
13 u16
14 }
15}
16
17impl Int for u8 {
18 fn to_u16(&self) -> u16 {
19 *self as u16
20 }
21 fn from_u16(u16: u16) -> Self {
22 u16 as u8
23 }
24}
25impl Int for u32 {
26 fn to_u16(&self) -> u16 {
27 *self as u16
28 }
29 fn from_u16(u16: u16) -> Self {
30 u16 as u32
31 }
32}
33impl Int for u64 {
34 fn to_u16(&self) -> u16 {
35 *self as u16
36 }
37 fn from_u16(u16: u16) -> Self {
38 u16 as u64
39 }
40}
41impl Int for u128 {
42 fn to_u16(&self) -> u16 {
43 *self as u16
44 }
45 fn from_u16(u16: u16) -> Self {
46 u16 as u128
47 }
48}
49impl Int for usize {
50 fn to_u16(&self) -> u16 {
51 *self as u16
52 }
53 fn from_u16(u16: u16) -> Self {
54 u16 as usize
55 }
56}
57
58impl Int for i8 {
59 fn to_u16(&self) -> u16 {
60 *self as u16
61 }
62 fn from_u16(u16: u16) -> Self {
63 u16 as i8
64 }
65}
66impl Int for i16 {
67 fn to_u16(&self) -> u16 {
68 *self as u16
69 }
70 fn from_u16(u16: u16) -> Self {
71 u16 as i16
72 }
73}
74impl Int for i32 {
75 fn to_u16(&self) -> u16 {
76 *self as u16
77 }
78 fn from_u16(u16: u16) -> Self {
79 u16 as i32
80 }
81}
82impl Int for i64 {
83 fn to_u16(&self) -> u16 {
84 *self as u16
85 }
86 fn from_u16(u16: u16) -> Self {
87 u16 as i64
88 }
89}
90impl Int for i128 {
91 fn to_u16(&self) -> u16 {
92 *self as u16
93 }
94 fn from_u16(u16: u16) -> Self {
95 u16 as i128
96 }
97}
98impl Int for isize {
99 fn to_u16(&self) -> u16 {
100 *self as u16
101 }
102 fn from_u16(u16: u16) -> Self {
103 u16 as isize
104 }
105}
106
107
108
109pub trait Vec2: Sized {
110 fn x(&self) -> u16;
111 fn y(&self) -> u16;
112 fn new(x: u16, y: u16) -> Self;
113
114 fn from<T: Vec2>(t: &T) -> Self {
115 Self::new(t.x(), t.y())
116 }
117 fn into<T: Vec2>(&self) -> T {
118 T::from(self)
119 }
120}
121
122impl<N1: Int, N2: Int> Vec2 for (N1, N2) {
123 fn x(&self) -> u16 {
124 self.0.to_u16()
125 }
126 fn y(&self) -> u16 {
127 self.1.to_u16()
128 }
129 fn new(x: u16, y: u16) -> Self {
130 (N1::from_u16(x), N2::from_u16(y))
131 }
132}
133
134pub type DefVec2 = (u16, u16);
135
136pub trait Rect: Sized {
137 fn left(&self) -> u16;
138 fn top(&self) -> u16;
139 fn h(&self) -> u16;
140 fn w(&self) -> u16;
141 fn new(left: u16, top: u16, w: u16, h: u16) -> Self;
142
143 fn bottom(&self) -> u16 {
144 self.top() + self.h() - 1
145 }
146 fn right(&self) -> u16 {
147 self.left() + self.w() - 1
148 }
149
150 fn top_left(&self) -> DefVec2 {
151 (self.left(), self.top())
152 }
153 fn top_right(&self) -> DefVec2 {
154 (self.right(), self.top())
155 }
156 fn bottom_left(&self) -> DefVec2 {
157 (self.left(), self.bottom())
158 }
159 fn bottom_right(&self) -> DefVec2 {
160 (self.right(), self.bottom())
161 }
162
163 fn from<T: Rect>(t: &T) -> Self {
164 Self::new(t.left(), t.top(), t.w(), t.h())
165 }
166 fn into<T: Rect>(&self) -> T {
167 T::from(self)
168 }
169}
170
171impl<V1: Vec2, V2: Vec2> Rect for (V1, V2) {
172 fn top(&self) -> u16 {
173 self.0.y().min(self.1.y())
174 }
175 fn left(&self) -> u16 {
176 self.0.x().min(self.1.x())
177 }
178 fn h(&self) -> u16 {
179 self.0.y().max(self.1.y()) - self.top() + 1
180 }
181 fn w(&self) -> u16 {
182 self.0.x().max(self.1.x()) - self.left() + 1
183 }
184 fn new(left: u16, top: u16, w: u16, h: u16) -> Self where Self: Sized {
185 (V1::new(left, top), V2::new(left + w - 1, top + h - 1))
186 }
187}
188
189pub type DefRect = (DefVec2, DefVec2);
190
191
192#[cfg(test)]
193mod geometry_tests {
194 use super::*;
195
196 #[test]
197 fn rect_works() {
198 let r1 = DefRect::new(1, 2, 1, 1);
199 let r2 = DefRect::new(3, 5, 2, 2);
200
201 assert_eq!(r1, ((1, 2), (1, 2)));
202 assert_eq!(r2, ((3, 5), (4, 6)));
203 }
204
205 #[test]
206 fn rect_size() {
207 let r1 = DefRect::new(1, 2, 1, 1);
208
209 assert_eq!(r1.w(), 1);
210 assert_eq!(r1.h(), 1);
211 assert_eq!(r1.bottom_right(), (1, 2));
212 }
213}
214