use kittycad_execution_plan_macros::ExecutionPlanValue;
use serde::{Deserialize, Serialize};
use crate::shared::{Point2d, Point3d, Point4d};
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize, ExecutionPlanValue, Default)]
pub struct LengthUnit(pub f64);
impl LengthUnit {
pub fn to_millimeters(&self, from: crate::units::UnitLength) -> f64 {
from.convert_to(crate::units::UnitLength::Millimeters, self.0)
}
pub fn from_millimeters(&self, to: crate::units::UnitLength) -> LengthUnit {
LengthUnit(crate::units::UnitLength::Millimeters.convert_to(to, self.0))
}
}
impl Point3d<LengthUnit> {
pub fn to_millimeters(&self, from: crate::units::UnitLength) -> Point3d<f64> {
Point3d {
x: self.x.to_millimeters(from),
y: self.y.to_millimeters(from),
z: self.z.to_millimeters(from),
}
}
}
impl Point3d<f64> {
pub fn from_millimeters(&self, to: crate::units::UnitLength) -> Point3d<LengthUnit> {
Point3d {
x: crate::units::UnitLength::Millimeters.convert_to(to, self.x).into(),
y: crate::units::UnitLength::Millimeters.convert_to(to, self.y).into(),
z: crate::units::UnitLength::Millimeters.convert_to(to, self.z).into(),
}
}
}
impl Point2d<LengthUnit> {
pub fn to_millimeters(&self, from: crate::units::UnitLength) -> Point2d<f64> {
Point2d {
x: self.x.to_millimeters(from),
y: self.y.to_millimeters(from),
}
}
}
impl Point2d<f64> {
pub fn from_millimeters(&self, to: crate::units::UnitLength) -> Point2d<LengthUnit> {
Point2d {
x: crate::units::UnitLength::Millimeters.convert_to(to, self.x).into(),
y: crate::units::UnitLength::Millimeters.convert_to(to, self.y).into(),
}
}
}
impl Point4d<LengthUnit> {
pub fn to_millimeters(&self, from: crate::units::UnitLength) -> Point4d<f64> {
Point4d {
x: self.x.to_millimeters(from),
y: self.y.to_millimeters(from),
z: self.z.to_millimeters(from),
w: self.w.0,
}
}
}
impl Point4d<f64> {
pub fn from_millimeters(&self, to: crate::units::UnitLength) -> Point4d<LengthUnit> {
Point4d {
x: crate::units::UnitLength::Millimeters.convert_to(to, self.x).into(),
y: crate::units::UnitLength::Millimeters.convert_to(to, self.y).into(),
z: crate::units::UnitLength::Millimeters.convert_to(to, self.z).into(),
w: LengthUnit(self.w),
}
}
}
impl schemars::JsonSchema for LengthUnit {
fn schema_name() -> String {
"LengthUnit".to_string()
}
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
<f64>::json_schema(gen)
}
}
impl From<f64> for LengthUnit {
fn from(value: f64) -> Self {
LengthUnit(value)
}
}
impl std::ops::Neg for LengthUnit {
type Output = Self;
fn neg(self) -> Self::Output {
LengthUnit(-self.0)
}
}
impl std::ops::Add for LengthUnit {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
LengthUnit(self.0 + rhs.0)
}
}
impl std::ops::Sub for LengthUnit {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
LengthUnit(self.0 - rhs.0)
}
}
impl std::ops::Mul<f64> for LengthUnit {
type Output = Self;
fn mul(self, rhs: f64) -> Self::Output {
LengthUnit(self.0 * rhs)
}
}
impl std::ops::Div<f64> for LengthUnit {
type Output = Self;
fn div(self, rhs: f64) -> Self::Output {
LengthUnit(self.0 / rhs)
}
}