#[cfg(feature = "diesel")]
use std::str::FromStr;
#[cfg(feature = "diesel")]
use diesel::{mysql::Mysql, serialize::ToSql, sql_types::Text};
#[cfg(feature = "diesel")]
use diesel_derives::{AsExpression, FromSqlRow};
use kittycad_execution_plan_macros::ExecutionPlanValue;
use kittycad_unit_conversion_derive::UnitConversion;
use parse_display_derive::{Display, FromStr};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
macro_rules! impl_string_enum_sql {
{$name:ident} => {
#[cfg(feature = "diesel")]
impl diesel::serialize::ToSql<Text, Mysql> for $name {
fn to_sql<'a>(&'a self, out: &mut diesel::serialize::Output<'a, '_, Mysql>) -> diesel::serialize::Result {
<String as ToSql<Text, Mysql>>::to_sql(&self.to_string(), &mut out.reborrow())
}
}
#[cfg(feature = "diesel")]
impl<DB> diesel::deserialize::FromSql<Text, DB> for $name
where
DB: diesel::backend::Backend,
String: diesel::deserialize::FromSql<Text, DB>,
{
fn from_sql(bytes: <DB as diesel::backend::Backend>::RawValue<'_>) -> diesel::deserialize::Result<Self> {
Ok(Self::from_str(&String::from_sql(bytes)?)?)
}
}
};
}
#[derive(
Default,
Display,
FromStr,
Copy,
Eq,
PartialEq,
Debug,
JsonSchema,
Deserialize,
Serialize,
Clone,
Ord,
PartialOrd,
UnitConversion,
Hash,
ExecutionPlanValue,
)]
#[display(style = "snake_case")]
pub enum UnitLength {
#[serde(rename = "cm")]
#[display("cm")]
Centimeters,
#[serde(rename = "ft")]
#[display("ft")]
Feet,
#[serde(rename = "in")]
#[display("in")]
Inches,
#[default]
#[serde(rename = "m")]
#[display("m")]
Meters,
#[serde(rename = "mm")]
#[display("mm")]
Millimeters,
#[serde(rename = "yd")]
#[display("yd")]
Yards,
}
impl UnitLength {
pub fn as_measurement(self, value: f64) -> measurements::Length {
match self {
Self::Centimeters => measurements::Length::from_centimeters(value),
Self::Feet => measurements::Length::from_feet(value),
Self::Inches => measurements::Length::from_inches(value),
Self::Meters => measurements::Length::from_meters(value),
Self::Millimeters => measurements::Length::from_millimeters(value),
Self::Yards => measurements::Length::from_yards(value),
}
}
}
#[derive(
Display,
FromStr,
Copy,
Eq,
PartialEq,
Debug,
JsonSchema,
Deserialize,
Serialize,
Clone,
Ord,
PartialOrd,
UnitConversion,
)]
#[cfg_attr(feature = "diesel", derive(AsExpression, FromSqlRow))]
#[cfg_attr(feature = "diesel", diesel(sql_type = Text))]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
pub enum UnitAngle {
Degrees,
Radians,
}
impl_string_enum_sql!(UnitAngle);
#[derive(
Display,
FromStr,
Copy,
Eq,
PartialEq,
Debug,
JsonSchema,
Deserialize,
Serialize,
Clone,
Ord,
PartialOrd,
UnitConversion,
Default,
Hash,
ExecutionPlanValue,
)]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
pub enum UnitArea {
#[serde(rename = "cm2")]
#[display("cm2")]
SquareCentimeters,
#[serde(rename = "dm2")]
#[display("dm2")]
SquareDecimeters,
#[serde(rename = "ft2")]
#[display("ft2")]
SquareFeet,
#[serde(rename = "in2")]
#[display("in2")]
SquareInches,
#[serde(rename = "km2")]
#[display("km2")]
SquareKilometers,
#[default]
#[serde(rename = "m2")]
#[display("m2")]
SquareMeters,
#[serde(rename = "mm2")]
#[display("mm2")]
SquareMillimeters,
#[serde(rename = "yd2")]
#[display("yd2")]
SquareYards,
}
impl UnitArea {
pub fn as_measurement(self, value: f64) -> measurements::Area {
match self {
Self::SquareCentimeters => measurements::Area::from_square_centimeters(value),
Self::SquareDecimeters => measurements::Area::from_square_decimeters(value),
Self::SquareFeet => measurements::Area::from_square_feet(value),
Self::SquareInches => measurements::Area::from_square_inches(value),
Self::SquareKilometers => measurements::Area::from_square_kilometers(value),
Self::SquareMeters => measurements::Area::from_square_meters(value),
Self::SquareMillimeters => measurements::Area::from_square_millimeters(value),
Self::SquareYards => measurements::Area::from_square_yards(value),
}
}
}
#[derive(
Display,
FromStr,
Copy,
Eq,
PartialEq,
Debug,
JsonSchema,
Deserialize,
Serialize,
Clone,
Ord,
PartialOrd,
Default,
UnitConversion,
Hash,
ExecutionPlanValue,
)]
#[display(style = "snake_case")]
pub enum UnitDensity {
#[serde(rename = "lb:ft3")]
#[display("lb:ft3")]
PoundsPerCubicFeet,
#[default]
#[serde(rename = "kg:m3")]
#[display("kg:m3")]
KilogramsPerCubicMeter,
}
impl UnitDensity {
pub fn as_measurement(self, value: f64) -> measurements::Density {
match self {
Self::PoundsPerCubicFeet => measurements::Density::from_pounds_per_cubic_feet(value),
Self::KilogramsPerCubicMeter => measurements::Density::from_kilograms_per_cubic_meter(value),
}
}
}
#[derive(
Default,
Display,
FromStr,
Copy,
Eq,
PartialEq,
Debug,
JsonSchema,
Deserialize,
Serialize,
Clone,
Ord,
PartialOrd,
UnitConversion,
Hash,
ExecutionPlanValue,
)]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
pub enum UnitMass {
#[default]
#[serde(rename = "g")]
#[display("g")]
Grams,
#[serde(rename = "kg")]
#[display("kg")]
Kilograms,
#[serde(rename = "lb")]
#[display("lb")]
Pounds,
}
impl UnitMass {
pub fn as_measurement(self, value: f64) -> measurements::Mass {
match self {
Self::Grams => measurements::Mass::from_grams(value),
Self::Kilograms => measurements::Mass::from_kilograms(value),
Self::Pounds => measurements::Mass::from_pounds(value),
}
}
}
#[derive(
Default,
Display,
FromStr,
Copy,
Eq,
PartialEq,
Debug,
JsonSchema,
Deserialize,
Serialize,
Clone,
Ord,
PartialOrd,
UnitConversion,
Hash,
ExecutionPlanValue,
)]
#[display(style = "snake_case")]
pub enum UnitVolume {
#[serde(rename = "cm3")]
#[display("cm3")]
CubicCentimeters,
#[serde(rename = "ft3")]
#[display("ft3")]
CubicFeet,
#[serde(rename = "in3")]
#[display("in3")]
CubicInches,
#[default]
#[serde(rename = "m3")]
#[display("m3")]
CubicMeters,
#[serde(rename = "yd3")]
#[display("yd3")]
CubicYards,
#[serde(rename = "usfloz")]
#[display("usfloz")]
FluidOunces,
#[serde(rename = "usgal")]
#[display("usgal")]
Gallons,
#[serde(rename = "l")]
#[display("l")]
Liters,
#[serde(rename = "ml")]
#[display("ml")]
Milliliters,
}
impl UnitVolume {
pub fn as_measurement(self, value: f64) -> measurements::Volume {
match self {
Self::CubicCentimeters => measurements::Volume::from_cubic_centimeters(value),
Self::CubicFeet => measurements::Volume::from_cubic_feet(value),
Self::CubicInches => measurements::Volume::from_cubic_inches(value),
Self::CubicMeters => measurements::Volume::from_cubic_meters(value),
Self::CubicYards => measurements::Volume::from_cubic_yards(value),
Self::FluidOunces => measurements::Volume::from_fluid_ounces(value),
Self::Gallons => measurements::Volume::from_gallons(value),
Self::Liters => measurements::Volume::from_liters(value),
Self::Milliliters => measurements::Volume::from_milliliters(value),
}
}
}