use std::iter::Sum;
use std::ops::{Add, AddAssign, Sub, SubAssign};
use crate::Orientation;
#[derive(Clone, Debug, Copy, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Vec2<T = usize> {
pub x: T,
pub y: T,
}
impl<T> Vec2<T> {
pub const fn new(x: T, y: T) -> Self {
Self { x, y }
}
}
impl<T: Copy> Vec2<T> {
pub const fn in_orientation(&self, orientation: Orientation) -> T {
match orientation {
Orientation::Vertical => self.y,
Orientation::Horizontal => self.x,
}
}
}
impl Vec2 {
pub const fn saturating_sub(self, other: Self) -> Self {
Self {
x: self.x.saturating_sub(other.x),
y: self.y.saturating_sub(other.y),
}
}
}
impl<T: Add<Output = T>> Add for Vec2<T> {
type Output = Self;
fn add(self, other: Self) -> Self::Output {
Self {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
impl<T: AddAssign<T>> AddAssign for Vec2<T> {
fn add_assign(&mut self, other: Self) {
self.x += other.x;
self.y += other.y;
}
}
impl<T: Sub<Output = T>> Sub for Vec2<T> {
type Output = Self;
fn sub(self, other: Self) -> Self::Output {
Self {
x: self.x - other.x,
y: self.y - other.y,
}
}
}
impl<T> Sum<Vec2<T>> for Vec2<T>
where
T: AddAssign + Default,
{
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = Self>,
{
let mut total = Self::default();
for i in iter {
total += i
}
total
}
}
impl<T: SubAssign<T>> SubAssign for Vec2<T> {
fn sub_assign(&mut self, other: Self) {
self.x -= other.x;
self.y -= other.y;
}
}
impl<T> From<(T, T)> for Vec2<T> {
fn from(value: (T, T)) -> Self {
Self {
x: value.0,
y: value.1,
}
}
}