Skip to main content

blockworx/router/
coord.rs

1// This is a lattice point on the grid.  The grid is double ended
2// and the coordinates can be negative, so we use a signed integer.
3// We use two newtype wrappers to handle the two axes.
4macro_rules! define_coord {
5    ($name:ident) => {
6        #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7        pub struct $name(i32);
8
9        impl $name {
10            /// The grid origin on this axis.
11            pub const ZERO: Self = $name(0);
12
13            pub fn min(self, other: Self) -> Self {
14                $name(self.0.min(other.0))
15            }
16
17            pub fn max(self, other: Self) -> Self {
18                $name(self.0.max(other.0))
19            }
20
21            pub fn abs(self) -> i32 {
22                self.0.abs()
23            }
24
25            pub fn raw(self) -> i32 {
26                self.0
27            }
28        }
29
30        impl From<f32> for $name {
31            fn from(value: f32) -> Self {
32                $name((value / crate::grid::GRID_SIZE).round() as i32)
33            }
34        }
35
36        impl From<i32> for $name {
37            fn from(value: i32) -> Self {
38                $name(value)
39            }
40        }
41
42        impl std::fmt::Display for $name {
43            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44                write!(f, "{}", self.0)
45            }
46        }
47
48        impl std::ops::Add for $name {
49            type Output = Self;
50            fn add(self, rhs: Self) -> Self {
51                $name(self.0 + rhs.0)
52            }
53        }
54
55        impl std::ops::Add<i32> for $name {
56            type Output = Self;
57            fn add(self, rhs: i32) -> Self {
58                $name(self.0 + rhs)
59            }
60        }
61
62        impl std::ops::Sub for $name {
63            type Output = Self;
64            fn sub(self, rhs: Self) -> Self {
65                $name(self.0 - rhs.0)
66            }
67        }
68
69        impl std::ops::Sub<i32> for $name {
70            type Output = Self;
71            fn sub(self, rhs: i32) -> Self {
72                $name(self.0 - rhs)
73            }
74        }
75    };
76}
77
78define_coord!(CoordX);
79define_coord!(CoordY);
80
81pub const INFINITY_X: CoordX = CoordX(i32::MAX >> 4);
82pub const INFINITY_Y: CoordY = CoordY(i32::MAX >> 4);
83pub const NEG_INFINITY_X: CoordX = CoordX(i32::MIN >> 4);
84pub const NEG_INFINITY_Y: CoordY = CoordY(i32::MIN >> 4);