bog/
rect.rs

1//! Rectangle Objects
2
3
4
5use std::fmt::Debug;
6
7use crate::prelude::Xy;
8
9
10
11// ================================================================================================
12
13
14
15pub struct Rect<T> {
16    pub min: Xy<T>,
17    pub max: Xy<T>,
18}
19
20impl <T> Rect<T> {
21    pub fn new(min_x: T, min_y: T, max_x: T, max_y: T) -> Self {
22        Self {
23            min: Xy::new(min_x, min_y),
24            max: Xy::new(max_x, max_y),
25        }
26    }
27}
28
29impl<T: PartialOrd> Rect<T> {
30    pub fn intersects(&self, other: &Self) -> bool {
31        self.min.x < other.max.x
32            && self.max.x > other.min.x
33            && self.min.y < other.max.y
34            && self.max.y > other.min.y
35    }
36
37    pub fn contains(self, xy: Xy<T>) -> bool {
38        xy.x >= self.min.x
39            && xy.x < self.max.x
40            && xy.y >= self.min.y
41            && xy.y < self.max.y
42    }
43}
44
45impl<T: Copy> Rect<T> {
46    pub fn left(&self) -> T {
47        self.min.x
48    }
49
50    pub fn right(&self) -> T {
51        self.max.x
52    }
53
54    pub fn top(&self) -> T {
55        self.min.y
56    }
57    
58    pub fn bottom(&self) -> T {
59        self.max.y
60    }
61}
62
63
64
65// ================================================================================================
66
67
68
69impl<T: Clone> Clone for Rect<T> {
70    fn clone(&self) -> Self {
71        Self {
72            min: self.min.clone(),
73            max: self.max.clone(),
74        }
75    }
76}
77
78impl<T: Copy> Copy for Rect<T> {}
79
80impl<T: Debug> Debug for Rect<T> {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        f.debug_struct("Rect")
83            .field("min", &self.min)
84            .field("max", &self.max)
85            .finish()
86    }
87}
88
89impl<T: Default> Default for Rect<T> {
90    fn default() -> Self {
91        Self {
92            min: Xy::default(),
93            max: Xy::default(),
94        }
95    }
96}
97
98impl<T: Eq> Eq for Rect<T> {}
99
100impl<T: PartialEq> PartialEq for Rect<T> {
101    fn eq(&self, other: &Self) -> bool {
102        self.min == other.min && self.max == other.max
103    }
104}
105
106
107
108// ================================================================================================
109
110
111
112#[cfg(test)]
113mod tests {
114    use super::*;
115
116    /// Assert that [`Rect`] implements Debug, Eq, Clone, etc... whenever its generic does.
117    #[test]
118    fn assert_implementations() {
119        let u32rect_a: Rect<u32> = Rect::new(1, 3, 2, 4);
120        let u32rect_b: Rect<u32> = Rect::new(3, 1, 4, 2);
121
122        assert_eq!(u32rect_a, u32rect_a.clone());
123        assert_ne!(u32rect_a, u32rect_b);
124    }
125}