use std::ops::Add; #[derive(Debug, Copy, Clone)] pub struct Point { x: u32, y: u32, } #[derive(Debug, Copy, Clone)] pub struct Rectangle { x: u32, y: u32, width: u32, height: u32, } impl Point { pub fn new(x: u32, y: u32) -> Self { Self { x, y } } pub fn origin() -> Self { Self { x: 0, y: 0 } } pub fn with_x(&mut self, x: u32) -> &mut Self { self.x = x; self } pub fn with_y(&mut self, y: u32) -> &mut Self { self.y = y; self } pub fn x(&self) -> u32 { self.x } pub fn y(&self) -> u32 { self.y } pub fn left_of(&self, other: &Self) -> bool { self.x < other.x } pub fn right_of(&self, other: &Self) -> bool { self.x > other.x } pub fn above(&self, other: &Self) -> bool { self.y < other.y } pub fn below(&self, other: &Self) -> bool { self.y > other.y } } impl Add for Point { type Output = Point; fn add(self, other: Point) -> Point { Point { x: self.x + other.x, y: self.y + other.y, } } } impl PartialEq for Point { fn eq(&self, other: &Self) -> bool { self.x == other.x && self.y == other.y } } impl Eq for Point {} #[cfg(test)] mod tests { use super::*; #[test] fn test_point_get_x() { assert_eq!(Point::new(42, 52).x(), 42); } #[test] fn test_point_get_y() { assert_eq!(Point::new(42, 52).y(), 52); } #[test] fn test_point_set_x() { assert_eq!(Point::new(42, 52).with_x(12), &Point::new(12, 52)); } #[test] fn test_point_set_y() { assert_eq!(Point::new(42, 52).with_y(12), &Point::new(42, 12)); } #[test] fn test_point_left_of() { assert!(Point::new(10, 20).left_of(&Point::new(20, 20))); assert!(!Point::new(10, 11).left_of(&Point::new(10, 11))); assert!(!Point::new(10, 11).left_of(&Point::new(8, 11))); } #[test] fn test_point_right_of() { assert!(Point::new(10, 20).right_of(&Point::new(0, 20))); assert!(!Point::new(10, 11).right_of(&Point::new(10, 11))); assert!(!Point::new(10, 11).right_of(&Point::new(12, 11))); } #[test] fn test_point_above() { assert!(Point::new(1, 1).above(&Point::new(1, 2))); assert!(!Point::new(10, 11).above(&Point::origin())); } #[test] fn test_point_below() { assert!(Point::new(1, 1).below(&Point::new(1, 0))); assert!(!Point::new(10, 11).below(&Point::new(12, 11))); } #[test] fn test_point_add() { assert_eq!(Point::new(1, 1) + Point::new(10, 10), Point::new(11, 11)); assert_eq!( Point::new(10, 0) + Point::new(0, 10), Point::new(0, 10) + Point::new(10, 0) ); } }