jay_algorithms/
rect.rs

1pub mod region;
2
3use {
4    smallvec::SmallVec,
5    std::fmt::{Debug, Formatter},
6};
7
8pub trait Tag: Copy + Eq + Ord + Debug + Default + Sized {
9    const IS_SIGNIFICANT: bool;
10
11    fn constrain(self) -> Self;
12}
13
14#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Default)]
15pub struct NoTag;
16
17impl Tag for NoTag {
18    const IS_SIGNIFICANT: bool = false;
19
20    #[inline(always)]
21    fn constrain(self) -> Self {
22        Self
23    }
24}
25
26impl Tag for u32 {
27    const IS_SIGNIFICANT: bool = true;
28
29    #[inline(always)]
30    fn constrain(self) -> Self {
31        self & 1
32    }
33}
34
35#[derive(Copy, Clone, Eq, PartialEq, Default)]
36pub struct RectRaw<T = NoTag>
37where
38    T: Tag,
39{
40    pub x1: i32,
41    pub y1: i32,
42    pub x2: i32,
43    pub y2: i32,
44    pub tag: T,
45}
46
47impl<T> Debug for RectRaw<T>
48where
49    T: Tag,
50{
51    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52        let mut debug = f.debug_struct("Rect");
53        debug
54            .field("x1", &self.x1)
55            .field("y1", &self.y1)
56            .field("x2", &self.x2)
57            .field("y2", &self.y2)
58            .field("width", &(self.x2 - self.x1))
59            .field("height", &(self.y2 - self.y1));
60        if T::IS_SIGNIFICANT {
61            debug.field("tag", &self.tag);
62        }
63        debug.finish()
64    }
65}
66
67impl<T> RectRaw<T>
68where
69    T: Tag,
70{
71    fn is_empty(&self) -> bool {
72        self.x1 == self.x2 || self.y1 == self.y2
73    }
74}
75
76type Container<T = NoTag> = SmallVec<[RectRaw<T>; 1]>;