use crate::sealed::Sealed;
use crate::{Scalar, ScalarComposite, ScalarOrVector, ScalarOrVectorTransform};
use core::num::NonZeroUsize;
use glam::{Vec3Swizzles, Vec4Swizzles};
pub unsafe trait Vector<T: Scalar, const N: usize>: ScalarOrVector<Scalar = T> {}
macro_rules! impl_vector {
($($ty:ty: [$scalar:ty; $n:literal];)+) => {
$(
impl Sealed for $ty {}
impl ScalarComposite for $ty {
#[inline]
fn transform<F: ScalarOrVectorTransform>(self, f: &mut F) -> Self {
f.transform_vector(self)
}
}
unsafe impl ScalarOrVector for $ty {
type Scalar = $scalar;
const N: NonZeroUsize = NonZeroUsize::new($n).unwrap();
}
unsafe impl Vector<$scalar, $n> for $ty {}
)+
};
}
impl_vector! {
glam::Vec2: [f32; 2];
glam::Vec3: [f32; 3];
glam::Vec3A: [f32; 3];
glam::Vec4: [f32; 4];
glam::DVec2: [f64; 2];
glam::DVec3: [f64; 3];
glam::DVec4: [f64; 4];
glam::UVec2: [u32; 2];
glam::UVec3: [u32; 3];
glam::UVec4: [u32; 4];
glam::IVec2: [i32; 2];
glam::IVec3: [i32; 3];
glam::IVec4: [i32; 4];
glam::BVec2: [bool; 2];
glam::BVec3: [bool; 3];
glam::BVec4: [bool; 4];
}
pub trait VectorTruncateInto<T> {
fn truncate_into(self) -> T;
}
macro_rules! vec_trunc_impl {
($a:ty, $b:ty, $self:ident $(.$($e:tt)*)?) => {
impl VectorTruncateInto<$a> for $b {
fn truncate_into($self) -> $a {
$self $(. $($e)*)?
}
}
};
}
macro_rules! vec_trunc_impls {
($s:ty, $v2:ty, $v3:ty, $v4:ty) => {
vec_trunc_impl! {$s, $s, self}
vec_trunc_impl! {$s, $v2, self.x}
vec_trunc_impl! {$s, $v3, self.x}
vec_trunc_impl! {$s, $v4, self.x}
vec_trunc_impl! {$v2, $v2, self}
vec_trunc_impl! {$v2, $v3, self.xy()}
vec_trunc_impl! {$v2, $v4, self.xy()}
vec_trunc_impl! {$v3, $v3, self}
vec_trunc_impl! {$v3, $v4, self.xyz()}
vec_trunc_impl! {$v4, $v4, self}
};
}
vec_trunc_impls! { f32, glam::Vec2, glam::Vec3, glam::Vec4 }
vec_trunc_impls! { f64, glam::DVec2, glam::DVec3, glam::DVec4 }
vec_trunc_impls! { i32, glam::IVec2, glam::IVec3, glam::IVec4 }
vec_trunc_impls! { u32, glam::UVec2, glam::UVec3, glam::UVec4 }