#[cfg(feature = "cgmath")]
mod cgmath;
#[cfg(feature = "ext-ops")]
mod ext_ops;
#[cfg(feature = "num-traits")]
mod num_traits;
use core::fmt::{Display, Formatter};
use core::ops::{
Add,
AddAssign,
Div,
DivAssign,
Mul,
MulAssign,
Neg,
Sub,
SubAssign,
};
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Vec2<T> {
pub x: T,
pub y: T,
}
impl<T: Display> Display for Vec2<T> {
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
f.write_str("(")?;
Display::fmt(&self.x, f)?;
f.write_str(", ")?;
Display::fmt(&self.y, f)?;
f.write_str(")")
}
}
#[cfg(feature = "num-complex")]
impl<T> From<num_complex::Complex<T>> for Vec2<T> {
fn from(c: num_complex::Complex<T>) -> Vec2<T> {
Vec2 { x: c.re, y: c.im }
}
}
#[cfg(feature = "num-complex")]
impl<T> Into<num_complex::Complex<T>> for Vec2<T> {
fn into(self) -> num_complex::Complex<T> {
num_complex::Complex { re: self.x, im: self.y }
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Vec3<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<T: Display> Display for Vec3<T> {
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
f.write_str("(")?;
Display::fmt(&self.x, f)?;
f.write_str(", ")?;
Display::fmt(&self.y, f)?;
f.write_str(", ")?;
Display::fmt(&self.z, f)?;
f.write_str(")")
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Vec4<T> {
pub x: T,
pub y: T,
pub z: T,
pub w: T,
}
impl<T: Display> Display for Vec4<T> {
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
f.write_str("(")?;
Display::fmt(&self.x, f)?;
f.write_str(", ")?;
Display::fmt(&self.y, f)?;
f.write_str(", ")?;
Display::fmt(&self.z, f)?;
f.write_str(", ")?;
Display::fmt(&self.w, f)?;
f.write_str(")")
}
}
pub fn vec2<T>(x: T, y: T) -> Vec2<T> {
Vec2 { x, y }
}
pub fn vec3<T>(x: T, y: T, z: T) -> Vec3<T> {
Vec3 { x, y, z }
}
pub fn vec4<T>(x: T, y: T, z: T, w: T) -> Vec4<T> {
Vec4 { x, y, z, w }
}
macro_rules! impl_unary_ops {
{ $(impl $trait:ident::$fn:ident for $vec:ident($($field:ident),*);)* } => { $(
impl<T> $trait for $vec<T>
where T: $trait
{
type Output = $vec<<T as $trait>::Output>;
fn $fn(self) -> Self::Output {
$vec { $($field: $trait::$fn(self.$field)),* }
}
}
impl<'a, T> $trait for &'a $vec<T>
where &'a T: $trait
{
type Output = $vec<<&'a T as $trait>::Output>;
fn $fn(self) -> Self::Output {
$vec { $($field: $trait::$fn(&self.$field)),* }
}
}
)* };
}
macro_rules! impl_scalar_ops {
{ $(impl $trait:ident::$fn:ident for $vec:ident($($field:ident),*);)* } => { $(
impl<T> $trait<T> for $vec<T>
where T: Copy + $trait
{
type Output = $vec<<T as $trait>::Output>;
fn $fn(self, rhs: T) -> Self::Output {
$vec { $($field: $trait::$fn(self.$field, rhs)),* }
}
}
impl<'a, T> $trait<T> for &'a $vec<T>
where T: Copy,
&'a T: $trait<T>
{
type Output = $vec<<&'a T as $trait<T>>::Output>;
fn $fn(self, rhs: T) -> Self::Output {
$vec { $($field: $trait::$fn(&self.$field, rhs)),* }
}
}
impl<'r, T> $trait<&'r T> for $vec<T>
where T: $trait<&'r T>
{
type Output = $vec<<T as $trait<&'r T>>::Output>;
fn $fn(self, rhs: &'r T) -> Self::Output {
$vec { $($field: $trait::$fn(self.$field, &rhs)),* }
}
}
impl<'a, 'r, T> $trait<&'r T> for &'a $vec<T>
where &'a T: $trait<&'r T>
{
type Output = $vec<<&'a T as $trait<&'r T>>::Output>;
fn $fn(self, rhs: &'r T) -> Self::Output {
$vec { $($field: $trait::$fn(&self.$field, &rhs)),* }
}
}
)* };
}
macro_rules! impl_scalar_assign_ops {
{ $(impl $trait:ident::$fn:ident for $vec:ident($($field:ident),*);)* } => { $(
impl<T> $trait<T> for $vec<T>
where T: Copy + $trait
{
fn $fn(&mut self, rhs: T) {
$($trait::$fn(&mut self.$field, rhs);)*
}
}
impl<'r, T> $trait<&'r T> for $vec<T>
where T: $trait<&'r T>
{
fn $fn(&mut self, rhs: &'r T) {
$($trait::$fn(&mut self.$field, rhs);)*
}
}
)* };
}
macro_rules! impl_binary_ops {
{ $(impl $trait:ident::$fn:ident for $vec:ident($($field:ident),*);)* } => { $(
impl<T> $trait for $vec<T>
where T: $trait
{
type Output = $vec<<T as $trait>::Output>;
fn $fn(self, rhs: $vec<T>) -> Self::Output {
$vec { $($field: $trait::$fn(self.$field, rhs.$field)),* }
}
}
impl<'a, T> $trait<$vec<T>> for &'a $vec<T>
where &'a T: $trait<T>
{
type Output = $vec<<&'a T as $trait<T>>::Output>;
fn $fn(self, rhs: $vec<T>) -> Self::Output {
$vec { $($field: $trait::$fn(&self.$field, rhs.$field)),* }
}
}
impl<'r, T> $trait<&'r $vec<T>> for $vec<T>
where T: $trait<&'r T>
{
type Output = $vec<<T as $trait<&'r T>>::Output>;
fn $fn(self, rhs: &'r $vec<T>) -> Self::Output {
$vec { $($field: $trait::$fn(self.$field, &rhs.$field)),* }
}
}
impl<'a, 'r, T> $trait<&'r $vec<T>> for &'a $vec<T>
where &'a T: $trait<&'r T>
{
type Output = $vec<<&'a T as $trait<&'r T>>::Output>;
fn $fn(self, rhs: &'r $vec<T>) -> Self::Output {
$vec { $($field: $trait::$fn(&self.$field, &rhs.$field)),* }
}
}
)* };
}
macro_rules! impl_binary_assign_ops {
{ $(impl $trait:ident::$fn:ident for $vec:ident($($field:ident),*);)* } => { $(
impl<T> $trait for $vec<T>
where T: $trait
{
fn $fn(&mut self, rhs: $vec<T>) {
$($trait::$fn(&mut self.$field, rhs.$field);)*
}
}
impl<'r, T> $trait<&'r $vec<T>> for $vec<T>
where T: $trait<&'r T>
{
fn $fn(&mut self, rhs: &'r $vec<T>) {
$($trait::$fn(&mut self.$field, &rhs.$field);)*
}
}
)* };
}
macro_rules! impl_all {
{ $(impl $vec:ident($($field:ident: $t:ident),*; $n:expr);)* } => { $(
impl<T> $vec<T> {
pub fn convert<U>(self) -> $vec<U>
where T: Into<U>
{
$vec { $($field: self.$field.into()),* }
}
pub const fn new($($field: $t),*) -> $vec<T> {
$vec { $($field),* }
}
pub fn ref_convert<'a, U>(&'a self) -> $vec<U>
where &'a T: Into<U>
{
$vec { $($field: (&self.$field).into()),* }
}
pub fn try_convert<U>(self) -> Result<$vec<U>, <T as TryInto<U>>::Error>
where T: TryInto<U>
{
Ok($vec { $($field: self.$field.try_into()?),* })
}
pub fn try_ref_convert<'a, U>(&'a self) -> Result<$vec<U>, <&'a T as TryInto<U>>::Error>
where &'a T: TryInto<U>
{
Ok($vec { $($field: (&self.$field).try_into()?),* })
}
}
impl<T> From<($($t),*)> for $vec<T> {
fn from(t: ($($t),*)) -> $vec<T> {
let ($($field),*) = t;
$vec { $($field),* }
}
}
impl<T> From<[T; $n]> for $vec<T> {
fn from(a: [T; $n]) -> $vec<T> {
let mut iter = a.into_iter();
$(let $field = iter.next().unwrap();)*
$vec { $($field),* }
}
}
impl<T> Into<($($t),*)> for $vec<T> {
fn into(self) -> ($($t),*) {
($(self.$field),*)
}
}
impl<T> Into<[T; $n]> for $vec<T> {
fn into(self) -> [T; $n] {
[$(self.$field),*]
}
}
impl_unary_ops! {
impl Neg::neg for $vec($($field),*);
}
impl_scalar_ops! {
impl Div::div for $vec($($field),*);
impl Mul::mul for $vec($($field),*);
}
impl_scalar_assign_ops! {
impl DivAssign::div_assign for $vec($($field),*);
impl MulAssign::mul_assign for $vec($($field),*);
}
impl_binary_ops! {
impl Add::add for $vec($($field),*);
impl Div::div for $vec($($field),*);
impl Mul::mul for $vec($($field),*);
impl Sub::sub for $vec($($field),*);
}
impl_binary_assign_ops! {
impl AddAssign::add_assign for $vec($($field),*);
impl DivAssign::div_assign for $vec($($field),*);
impl MulAssign::mul_assign for $vec($($field),*);
impl SubAssign::sub_assign for $vec($($field),*);
}
)* };
}
impl_all! {
impl Vec2(x: T, y: T; 2);
impl Vec3(x: T, y: T, z: T; 3);
impl Vec4(x: T, y: T, z: T, w: T; 4);
}