common_stdx/
lib.rs

1mod point;
2pub use point::Point;
3
4use std::ops::{Add, Sub};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct Rect<T> {
8    pub p1: Point<T>,
9    pub p2: Point<T>,
10}
11
12impl<T> Rect<T> {
13    pub fn new(p1: Point<T>, p2: Point<T>) -> Self {
14        Rect { p1, p2 }
15    }
16
17    pub fn from_coords(x1: T, y1: T, x2: T, y2: T) -> Self {
18        Rect {
19            p1: Point { x: x1, y: y1 },
20            p2: Point { x: x2, y: y2 },
21        }
22    }
23}
24
25impl<T> Rect<T>
26where
27    T: Copy + Ord,
28{
29    pub fn normalized(self) -> Self {
30        let min_x = self.p1.x.min(self.p2.x);
31        let max_x = self.p1.x.max(self.p2.x);
32        let min_y = self.p1.y.min(self.p2.y);
33        let max_y = self.p1.y.max(self.p2.y);
34
35        Rect {
36            p1: Point { x: min_x, y: min_y },
37            p2: Point { x: max_x, y: max_y },
38        }
39    }
40
41    pub fn contains(&self, point: Point<T>) -> bool {
42        let r = self.normalized();
43        point.x >= r.p1.x && point.x <= r.p2.x && point.y >= r.p1.y && point.y <= r.p2.y
44    }
45}
46
47impl<T> Rect<T>
48where
49    T: Copy + Ord + Sub<Output = T>,
50{
51    pub fn width(&self) -> T {
52        let r = self.normalized();
53        r.p2.x - r.p1.x
54    }
55
56    pub fn height(&self) -> T {
57        let r = self.normalized();
58        r.p2.y - r.p1.y
59    }
60}
61
62impl<T> Rect<T>
63where
64    T: Copy + Ord + Add<Output = T> + Sub<Output = T> + std::ops::Mul<Output = T>,
65{
66    pub fn area(&self) -> T {
67        self.width() * self.height()
68    }
69}
70
71impl<T> Rect<T> {
72    pub fn map<U, F>(self, mut f: F) -> Rect<U>
73    where
74        F: FnMut(T) -> U,
75    {
76        Rect {
77            p1: Point {
78                x: f(self.p1.x),
79                y: f(self.p1.y),
80            },
81            p2: Point {
82                x: f(self.p2.x),
83                y: f(self.p2.y),
84            },
85        }
86    }
87}