use std::cmp::Eq; use std::fmt::Debug; use std::hash::Hash; use std::ops::{Add, Index, IndexMut, Mul, Sub}; #[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, C, I>(v: &'a [C], idx: &Vector2D<I>) -> &'a C::Output where I: Copy, C: Index<usize>, usize: TryFrom<I>, <usize as TryFrom<I>>::Error: Debug, { let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap()); &v[y][x] } pub fn index_mut<'a, C, I>(v: &'a mut [C], idx: &Vector2D<I>) -> &'a mut C::Output where I: Copy, C: IndexMut<usize>, usize: TryFrom<I>, <usize as TryFrom<I>>::Error: Debug, { let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap()); &mut v[y][x] } pub fn in_range<I, C>(v: &[Vec<C>], idx: &Vector2D<I>) -> bool where I: Copy, usize: TryFrom<I>, { usize::try_from(idx.y) .and_then(|y| usize::try_from(idx.x).map(|x| y < v.len() && x < v[y].len())) .unwrap_or(false) } 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: Sub + Sub<Output = U>, U> Sub for Vector2D<T> { type Output = Vector2D<U>; fn sub(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, } } }