1
0
Fork 0
2022/src/vector2d.rs

128 lines
2.8 KiB
Rust
Raw Normal View History

use std::cmp::Eq;
use std::fmt::Debug;
use std::hash::Hash;
2022-12-30 12:11:41 +01:00
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
}
}
2022-12-30 12:11:41 +01:00
pub fn index<'a, C, I>(v: &'a [C], idx: &Vector2D<I>) -> &'a C::Output
where
2022-12-30 12:11:41 +01:00
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]
}
2022-12-30 12:11:41 +01:00
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<T, U>(v: &[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: 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,
}
}
}