Skip to main content

photon_ui/layout/
offset.rs

1/// Relative movement in the terminal coordinate system.
2#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
3pub struct Offset {
4    /// Horizontal offset (positive = right, negative = left).
5    pub x: i16,
6    /// Vertical offset (positive = down, negative = up).
7    pub y: i16,
8}
9
10impl Offset {
11    /// The largest possible offset.
12    pub const MAX: Self = Self::new(i16::MAX, i16::MAX);
13    /// The smallest possible offset.
14    pub const MIN: Self = Self::new(i16::MIN, i16::MIN);
15
16    /// Create a new offset with the given x and y values.
17    pub const fn new(x: i16, y: i16) -> Self {
18        Self { x, y }
19    }
20}
21
22impl std::ops::Add for Offset {
23    type Output = Self;
24
25    fn add(self, other: Self) -> Self::Output {
26        Self {
27            x: self.x.saturating_add(other.x),
28            y: self.y.saturating_add(other.y),
29        }
30    }
31}
32
33impl std::ops::Sub for Offset {
34    type Output = Self;
35
36    fn sub(self, other: Self) -> Self::Output {
37        Self {
38            x: self.x.saturating_sub(other.x),
39            y: self.y.saturating_sub(other.y),
40        }
41    }
42}
43
44impl std::ops::Neg for Offset {
45    type Output = Self;
46
47    fn neg(self) -> Self::Output {
48        Self {
49            x: self.x.saturating_neg(),
50            y: self.y.saturating_neg(),
51        }
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn offset_new() {
61        let o = Offset::new(5, -3);
62        assert_eq!(o.x, 5);
63        assert_eq!(o.y, -3);
64    }
65
66    #[test]
67    fn offset_add() {
68        let a = Offset::new(10, 20);
69        let b = Offset::new(5, -8);
70        assert_eq!(a + b, Offset::new(15, 12));
71    }
72
73    #[test]
74    fn offset_sub() {
75        let a = Offset::new(10, 20);
76        let b = Offset::new(5, 8);
77        assert_eq!(a - b, Offset::new(5, 12));
78    }
79
80    #[test]
81    fn offset_neg() {
82        let o = Offset::new(5, -3);
83        assert_eq!(-o, Offset::new(-5, 3));
84    }
85
86    #[test]
87    fn offset_add_saturates() {
88        let a = Offset::new(i16::MAX, i16::MAX);
89        let b = Offset::new(1, 1);
90        assert_eq!(a + b, Offset::new(i16::MAX, i16::MAX));
91    }
92
93    #[test]
94    fn offset_sub_saturates() {
95        let a = Offset::new(i16::MIN, i16::MIN);
96        let b = Offset::new(1, 1);
97        assert_eq!(a - b, Offset::new(i16::MIN, i16::MIN));
98    }
99}