use super::{Component, Vector};
use core::{
iter::FromIterator,
ops::{Add, AddAssign, Index, Mul, MulAssign, Sub, SubAssign},
};
pub type I8x2 = Vector2d<i8>;
pub type I16x2 = Vector2d<i16>;
pub type I32x2 = Vector2d<i32>;
pub type U8x2 = Vector2d<u8>;
pub type U16x2 = Vector2d<u16>;
pub type U32x2 = Vector2d<u32>;
pub type F32x2 = Vector2d<f32>;
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct Vector2d<C: Component> {
pub x: C,
pub y: C,
}
impl<C> Vector2d<C>
where
C: Component,
{
pub fn to_array(&self) -> [C; 2] {
[self.x, self.y]
}
}
impl<C> FromIterator<C> for Vector2d<C>
where
C: Component,
{
fn from_iter<T>(into_iter: T) -> Self
where
T: IntoIterator<Item = C>,
{
let mut iter = into_iter.into_iter();
let x = iter.next().expect("no x-axis component in slice");
let y = iter.next().expect("no y-axis component in slice");
assert!(
iter.next().is_none(),
"too many items for 2-dimensional vector"
);
Self { x, y }
}
}
impl<C> Vector<C> for Vector2d<C>
where
C: Component,
{
const AXES: usize = 2;
fn get(self, index: usize) -> Option<C> {
match index {
0 => Some(self.x),
1 => Some(self.y),
_ => None,
}
}
fn dot(self, rhs: Self) -> C {
(self.x * rhs.x) + (self.y * rhs.y)
}
}
impl<C> From<(C, C)> for Vector2d<C>
where
C: Component,
{
fn from(vector: (C, C)) -> Self {
Self {
x: vector.0,
y: vector.1,
}
}
}
impl<C> Index<usize> for Vector2d<C>
where
C: Component,
{
type Output = C;
fn index(&self, i: usize) -> &C {
match i {
0 => &self.x,
1 => &self.y,
_ => panic!("index out of range"),
}
}
}
impl<C> Add for Vector2d<C>
where
C: Component,
{
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl<C> AddAssign for Vector2d<C>
where
C: Component,
{
fn add_assign(&mut self, other: Self) {
*self = *self + other;
}
}
impl<C> Sub for Vector2d<C>
where
C: Component,
{
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl<C> SubAssign for Vector2d<C>
where
C: Component,
{
fn sub_assign(&mut self, other: Self) {
*self = *self - other;
}
}
impl<C> Mul<C> for Vector2d<C>
where
C: Component,
{
type Output = Self;
fn mul(self, rhs: C) -> Self {
Self {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl<C> MulAssign<C> for Vector2d<C>
where
C: Component,
{
fn mul_assign(&mut self, rhs: C) {
*self = *self * rhs;
}
}
impl From<I8x2> for F32x2 {
fn from(vector: I8x2) -> F32x2 {
Self {
x: vector.x.into(),
y: vector.y.into(),
}
}
}
impl From<I16x2> for F32x2 {
fn from(vector: I16x2) -> F32x2 {
Self {
x: vector.x.into(),
y: vector.y.into(),
}
}
}
impl From<U8x2> for F32x2 {
fn from(vector: U8x2) -> F32x2 {
Self {
x: vector.x.into(),
y: vector.y.into(),
}
}
}
impl From<U16x2> for F32x2 {
fn from(vector: U16x2) -> F32x2 {
Self {
x: vector.x.into(),
y: vector.y.into(),
}
}
}