layout_engine 0.7.0

A small project to mimic css flexbox and css grid
Documentation
use super::{LayoutInfo, Vec2};

/// A rectangle
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Rect {
    pub start: Vec2,
    pub size: Vec2,
}

impl Rect {
    pub const fn new(x: usize, y: usize, size_x: usize, size_y: usize) -> Self {
        Self {
            start: Vec2::new(x, y),
            size: Vec2::new(size_x, size_y),
        }
    }

    /// Gets the end of this rectangle.
    pub const fn end(&self) -> Vec2 {
        Vec2 {
            x: self.start.x + self.size.x,
            y: self.start.y + self.size.y,
        }
    }

    pub const fn layout_info_x(&self) -> LayoutInfo {
        LayoutInfo {
            start: self.start.x,
            end: self.end().x,
        }
    }

    pub const fn layout_info_y(&self) -> LayoutInfo {
        LayoutInfo {
            start: self.start.y,
            end: self.end().y,
        }
    }

    /// Determines if `point` is inside `self`'s bounds
    pub const fn contains(&self, point: Vec2) -> bool {
        self.start.x <= point.x
            && point.x < self.end().x
            && self.start.y <= point.y
            && point.y < self.end().y
    }

    // Determines if `other` is completely within this.
    pub const fn contains_rect(&self, other: Rect) -> bool {
        self.contains(other.start) && self.contains(other.end())
    }

    /// Determines if two rectangles overlap
    pub const fn intersects(self, other: Rect) -> bool {
        self.start.x < other.end().x
            && self.end().x > other.start.x
            && self.start.y < other.end().y
            && self.end().y > other.start.y
    }
}

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

    #[test]
    pub fn new() {
        assert_eq!(
            Rect::new(1, 2, 3, 4),
            Rect {
                start: Vec2::new(1, 2),
                size: Vec2::new(3, 4),
            }
        )
    }

    #[test]
    pub fn end() {
        let rect = Rect::new(1, 2, 3, 4);
        assert_eq!(rect.end(), Vec2::new(4, 6));
    }

    #[test]
    pub fn layout_info() {
        let rect = Rect::new(1, 2, 3, 4);

        assert_eq!(rect.layout_info_x(), LayoutInfo { start: 1, end: 4 });
        assert_eq!(rect.layout_info_y(), LayoutInfo { start: 2, end: 6 });
    }

    #[test]
    pub fn contains() {
        let rect = Rect::new(1, 2, 3, 4);

        assert!(!rect.contains(Vec2::new(0, 0)));
        assert!(!rect.contains(Vec2::new(0, 1)));
        assert!(!rect.contains(Vec2::new(0, 3)));
        assert!(!rect.contains(Vec2::new(5, 7)));
        assert!(!rect.contains(Vec2::new(4, 6)));
        assert!(!rect.contains_rect(Rect::new(6, 7, 2, 3)));

        assert!(rect.contains(Vec2::new(1, 2)));
        assert!(rect.contains(Vec2::new(2, 2)));
        assert!(rect.contains(Vec2::new(3, 3)));
        assert!(rect.contains_rect(Rect::new(2, 3, 1, 1)));
    }

    #[test]
    pub fn intersects() {
        let rect = Rect::new(1, 2, 3, 4);

        assert!(!rect.intersects(Rect::new(5, 7, 2, 2)));
        assert!(!rect.intersects(Rect::new(0, 0, 1, 1)));

        assert!(rect.intersects(Rect::new(0, 3, 8, 8)));
        assert!(rect.intersects(Rect::new(2, 3, 2, 3)));
        assert!(Rect::new(0, 1, 1, 2).intersects(Rect::new(0, 0, 1, 4)));
    }
}