macro_rules! semantic_newtype {
(
$(#[$meta:meta])*
$name:ident, $inner:ty
) => {
$(#[$meta])*
#[derive(Debug, Clone, Copy, PartialEq, Default, Reflect)]
pub struct $name(pub $inner);
impl $name {
pub const fn new(x: f32, y: f32, z: f32) -> Self {
Self(<$inner>::new(x, y, z))
}
pub const fn into_inner(self) -> $inner {
self.0
}
pub fn distance(self, other: impl Into<Self>) -> f32 {
self.0.distance(other.into().0)
}
pub fn distance_squared(self, other: impl Into<Self>) -> f32 {
self.0.distance_squared(other.into().0)
}
#[must_use]
pub fn lerp(self, other: impl Into<Self>, t: f32) -> Self {
Self(self.0.lerp(other.into().0, t))
}
}
impl core::ops::Deref for $name {
type Target = $inner;
fn deref(&self) -> &$inner {
&self.0
}
}
impl From<$inner> for $name {
fn from(value: $inner) -> Self {
Self(value)
}
}
impl From<$name> for $inner {
fn from(value: $name) -> Self {
value.0
}
}
impl core::ops::Add for $name {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self(self.0 + rhs.0)
}
}
impl core::ops::AddAssign for $name {
fn add_assign(&mut self, rhs: Self) {
self.0 += rhs.0;
}
}
impl core::ops::Sub for $name {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self(self.0 - rhs.0)
}
}
impl core::ops::SubAssign for $name {
fn sub_assign(&mut self, rhs: Self) {
self.0 -= rhs.0;
}
}
impl core::ops::Mul<f32> for $name {
type Output = Self;
fn mul(self, rhs: f32) -> Self {
Self(self.0 * rhs)
}
}
impl core::ops::MulAssign<f32> for $name {
fn mul_assign(&mut self, rhs: f32) {
self.0 *= rhs;
}
}
impl core::ops::Div<f32> for $name {
type Output = Self;
fn div(self, rhs: f32) -> Self {
Self(self.0 / rhs)
}
}
impl core::ops::DivAssign<f32> for $name {
fn div_assign(&mut self, rhs: f32) {
self.0 /= rhs;
}
}
impl core::ops::Neg for $name {
type Output = Self;
fn neg(self) -> Self {
Self(-self.0)
}
}
impl core::ops::Add<$inner> for $name {
type Output = Self;
fn add(self, rhs: $inner) -> Self {
Self(self.0 + rhs)
}
}
impl core::ops::AddAssign<$inner> for $name {
fn add_assign(&mut self, rhs: $inner) {
self.0 += rhs;
}
}
impl core::ops::Sub<$inner> for $name {
type Output = Self;
fn sub(self, rhs: $inner) -> Self {
Self(self.0 - rhs)
}
}
impl core::ops::SubAssign<$inner> for $name {
fn sub_assign(&mut self, rhs: $inner) {
self.0 -= rhs;
}
}
};
}