1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! Rectangle helper extensions.
//!
//! Extends the embedded-graphics [`Rectangle`] struct with some helper methods.
use embedded_graphics::{prelude::*, primitives::Rectangle};

/// [`Rectangle`] extensions
pub trait RectExt {
    /// Returns the (correct) size of a [`Rectangle`].
    fn size(self) -> Size;

    /// Sorts the coordinates of a [`Rectangle`] so that `top` < `bottom` and `left` < `right`.
    fn into_well_formed(self) -> Rectangle;
}

impl RectExt for Rectangle {
    #[inline]
    #[must_use]
    fn size(self) -> Size {
        // TODO: remove if fixed in embedded-graphics
        let width = (self.bottom_right.x - self.top_left.x) as u32 + 1;
        let height = (self.bottom_right.y - self.top_left.y) as u32 + 1;

        Size::new(width, height)
    }

    #[inline]
    #[must_use]
    fn into_well_formed(self) -> Rectangle {
        Rectangle::new(
            Point::new(
                self.top_left.x.min(self.bottom_right.x),
                self.top_left.y.min(self.bottom_right.y),
            ),
            Point::new(
                self.top_left.x.max(self.bottom_right.x),
                self.top_left.y.max(self.bottom_right.y),
            ),
        )
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_well_formed() {
        assert_eq!(
            Rectangle::new(Point::new(0, -4), Point::new(3, 0)),
            Rectangle::new(Point::new(3, -4), Point::zero()).into_well_formed()
        );
    }
}