Skip to main content

terminal_draw/
geometry.rs

1
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