use std::ops::{Add, AddAssign}; macro_rules! point { ( $x:expr, $y:expr ) => { Point2D { x:$x, y:$y } }; } #[derive(Debug, Copy, Clone, PartialEq)] pub struct Point2D { pub x: T, pub y: T, } impl Point2D { pub fn length(self) -> f64 { ((self.x * self.x) + (self.y * self.y)).sqrt() } } impl> Add for Point2D { type Output = Point2D; fn add(self, rhs: Point2D) -> Self::Output { Point2D { x: self.x + rhs.x, y: self.y + rhs.y } } } impl AddAssign for Point2D { fn add_assign(&mut self, rhs: Point2D) { self.x += rhs.x; self.y += rhs.y; } } #[cfg(test)] mod tests { use super::*; #[test] fn immutable_copy_of_point() { let a = point!(0, 0); let mut b = a; // Copy assert_eq!(a, b); // PartialEq b.x = 1; assert_ne!(a, b); // PartialEq } #[test] fn add_points() { let mut a = point!(1, 0); assert_eq!(a + point!(2, 2), point!(3, 2)); // Add a += point!(2, 2); // AddAssign assert_eq!(a, point!(3, 2)); } }