rect 0.1.0

generic rectangle defined as range of points
Documentation
pub mod i32 {
    use abs::abs;

    #[derive(Clone)]
    pub struct Point(i32, i32);

    #[derive(Clone)]
    pub struct Rect(std::ops::Range<Point>);

    impl Rect {
        pub fn width(&self) -> i32 {
            let x1 = self.0.start.0;
            let x2 = self.0.end.0;
            abs(x1, x2)
        }
        pub fn height(&self) -> i32 {
            let y1 = self.0.start.1;
            let y2 = self.0.end.1;
            abs(y1, y2)
        }
        pub fn area(&self) -> i32 {
            self.width() * self.height()
        }
    }
    #[cfg(test)]
    mod tests {
        use super::*;
        #[test]
        fn it_works() {
            let a = Point(-2, 2);
            let b = Point(-3, 5);
            let r = Rect(a..b);
            assert_eq!(r.width(), 1);
            assert_eq!(r.height(), 3);
            assert_eq!(r.area(), 3);
        }
    }
}

pub mod tuple {
    use abs::abs;

    #[derive(Clone)]
    pub struct Point<T>(T, T)
    where
        T: Clone + PartialOrd + std::ops::Sub<Output = T>;

    #[derive(Clone)]
    pub struct Rect<T>(std::ops::Range<Point<T>>)
    where
        T: Clone + PartialOrd + std::ops::Sub<Output = T>;

    impl<T> Rect<T>
    where
        T: Clone + PartialOrd + std::ops::Sub<Output = T> + std::ops::Mul<Output = T>,
    {
        pub fn width(&self) -> T {
            let x1 = self.0.clone().start.0;
            let x2 = self.0.clone().end.0;
            abs(x1, x2)
        }
        pub fn height(&self) -> T {
            let y1 = self.0.clone().start.1;
            let y2 = self.0.clone().end.1;
            abs(y1, y2)
        }
        pub fn area(&self) -> T {
            self.width() * self.height()
        }
    }
    #[cfg(test)]
    mod tests {
        use super::*;
        #[test]
        fn it_works() {
            let a = Point(-2, 2);
            let b = Point(-3, 5);
            let r = Rect(a..b);
            assert_eq!(r.width(), 1);
            assert_eq!(r.height(), 3);
            assert_eq!(r.area(), 3);
        }
    }
}

pub mod generic {
    use abs::abs;

    #[derive(Clone)]
    pub struct Point<T>
    where
        T: Clone + PartialOrd + std::ops::Sub<Output = T>,
    {
        pub x: T,
        pub y: T,
    }

    #[derive(Clone)]
    pub struct Rect<T>
    where
        T: Clone + PartialOrd + std::ops::Sub<Output = T>,
    {
        range: std::ops::Range<Point<T>>,
    }

    impl<T> Rect<T>
    where
        T: Clone + PartialOrd + std::ops::Sub<Output = T> + std::ops::Mul<Output = T>,
    {
        pub fn width(&self) -> T {
            let x1 = self.range.clone().start.x;
            let x2 = self.range.clone().end.x;
            abs(x1, x2)
        }
        pub fn height(&self) -> T {
            let y1 = self.range.clone().start.y;
            let y2 = self.range.clone().end.y;
            abs(y1, y2)
        }
        pub fn area(&self) -> T {
            self.width() * self.height()
        }
    }

    #[cfg(test)]
    mod tests {
        use super::*;
        #[test]
        fn it_works() {
            let a = Point { x: -2, y: 2 };
            let b = Point { x: -3, y: 5 };
            let r = Rect { range: a..b };
            assert_eq!(r.width(), 1);
            assert_eq!(r.height(), 3);
            assert_eq!(r.area(), 3);
        }
    }
}