use std::cmp::Eq; use std::fmt::Debug; use std::hash::Hash; use std::ops::{Add, Mul}; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Vector2D<T> { x: T, y: T, } impl<T> Vector2D<T> { pub fn new(x: T, y: T) -> Vector2D<T> { Vector2D { x, y } } pub fn x(&self) -> &T { &self.x } pub fn y(&self) -> &T { &self.y } } pub fn index<'a, T, U>(v: &'a [Vec<U>], idx: &Vector2D<T>) -> &'a U where usize: TryFrom<T>, <usize as TryFrom<T>>::Error: Debug, T: Copy, { let (x, y): (usize, usize) = (idx.y.try_into().unwrap(), idx.x.try_into().unwrap()); &v[y][x] } pub fn in_range<T, U>(v: &Vec<Vec<U>>, idx: &Vector2D<T>) -> bool where usize: TryInto<T>, <usize as TryInto<T>>::Error: Debug, usize: TryFrom<T>, <usize as TryFrom<T>>::Error: Debug, T: PartialOrd + Copy, { idx.y >= 0.try_into().unwrap() && idx.y < v.len().try_into().unwrap() && idx.x >= 0.try_into().unwrap() && idx.x < v[TryInto::<usize>::try_into(idx.y).unwrap()] .len() .try_into() .unwrap() } impl<T: Copy> Vector2D<T> { pub fn swap(&self) -> Self { Self { x: self.y, y: self.x, } } } // See: https://github.com/rust-lang/rust/issues/102731 // impl<U: From<T>, T> From<Vector2D<T>> for Vector2D<U> { // fn from(value: Vector2D<T>) -> Self { // Self { // x: U::from(value.x), // y: U::from(value.y), // } // } // } impl<T: Add + Add<Output = U>, U> Add for Vector2D<T> { type Output = Vector2D<U>; fn add(self, rhs: Self) -> Self::Output { Vector2D { x: self.x + rhs.x, y: self.y + rhs.y, } } } impl<T: Mul + Mul<Output = U>, U> Mul for Vector2D<T> { type Output = Vector2D<U>; fn mul(self, rhs: Self) -> Self::Output { Vector2D { x: self.x * rhs.x, y: self.y * rhs.y, } } } impl<T: Mul + Mul<Output = U> + Copy, U> Mul<T> for Vector2D<T> { type Output = Vector2D<U>; fn mul(self, rhs: T) -> Self::Output { Vector2D { x: self.x * rhs, y: self.y * rhs, } } }