complete rewrite
parent
b4f08b7ead
commit
5da5d770d9
|
@ -6,3 +6,4 @@ edition = "2021"
|
|||
[build-dependencies]
|
||||
quote = "1.0"
|
||||
proc-macro2 = "1.0"
|
||||
map-macro = "0.3.0"
|
||||
|
|
923
build.rs
923
build.rs
|
@ -1,149 +1,280 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
use quote::{
|
||||
format_ident,
|
||||
quote,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::ops::{Add, Div, Mul, Sub};
|
||||
use std::path::Path;
|
||||
use map_macro::hash_map;
|
||||
|
||||
#[derive(Default, Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Copy)]
|
||||
pub struct Matrix([i8; 7]);
|
||||
struct Dimension {
|
||||
name: &'static str,
|
||||
units: Vec<(&'static str, (f64, f64))>,
|
||||
}
|
||||
|
||||
impl Mul<i8> for Matrix {
|
||||
type Output = Matrix;
|
||||
fn mul(self, rhs: i8) -> Self::Output {
|
||||
let mut output = Matrix::default();
|
||||
for (i, v) in self.0.iter().enumerate() {
|
||||
output.0[i] = v * rhs;
|
||||
}
|
||||
output
|
||||
mod matricies {
|
||||
pub const Scalar: [i8; 7] = [0, 0, 0, 0, 0, 0, 0];
|
||||
pub const Time: [i8; 7] = [1, 0, 0, 0, 0, 0, 0];
|
||||
pub const Frequency: [i8; 7] = [-1, 0, 0, 0, 0, 0, 0];
|
||||
pub const Length: [i8; 7] = [0, 1, 0, 0, 0, 0, 0];
|
||||
pub const Area: [i8; 7] = [0, 2, 0, 0, 0, 0, 0];
|
||||
pub const Speed: [i8; 7] = [-1, 1, 0, 0, 0, 0, 0];
|
||||
pub const Acceleration: [i8; 7] = [-2, 1, 0, 0, 0, 0, 0];
|
||||
pub const Mass: [i8; 7] = [0, 0, 1, 0, 0, 0, 0];
|
||||
pub const MassPerDist: [i8; 7] = [0, -1, 1, 0, 0, 0, 0];
|
||||
pub const Density: [i8; 7] = [0, -3, 1, 0, 0, 0, 0];
|
||||
pub const MassMoment: [i8; 7] = [0, 2, 1, 0, 0, 0, 0];
|
||||
pub const Force: [i8; 7] = [-2, 1, 1, 0, 0, 0, 0];
|
||||
pub const ForceMoment: [i8; 7] = [-2, 2, 1, 0, 0, 0, 0];
|
||||
pub const Pressure: [i8; 7] = [-2, -1, 1, 0, 0, 0, 0];
|
||||
pub const Energy: [i8; 7] = [-2, 2, 1, 0, 0, 0, 0];
|
||||
pub const Power: [i8; 7] = [-3, 2, 1, 0, 0, 0, 0];
|
||||
pub const Current: [i8; 7] = [0, 0, 0, 1, 0, 0, 0];
|
||||
pub const Charge: [i8; 7] = [1, 0, 0, 1, 0, 0, 0];
|
||||
pub const Capacitance: [i8; 7] = [4, -2, -1, 1, 0, 0, 0];
|
||||
pub const Potential: [i8; 7] = [-3, -2, 1, -1, 0, 0, 0];
|
||||
pub const Resistance: [i8; 7] = [-3, 2, 1, -2, 0, 0, 0];
|
||||
pub const Conductance: [i8; 7] = [3, -2, -1, 2, 0, 0, 0];
|
||||
pub const Flux: [i8; 7] = [-2, 2, 1, -1, 0, 0, 0];
|
||||
pub const FluxDensity: [i8; 7] = [2, 0, 1, -1, 0, 0, 0];
|
||||
pub const Inductance: [i8; 7] = [-2, 2, 1, -2, 0, 0, 0];
|
||||
pub const Temperature: [i8; 7] = [0, 0, 0, 0, 1, 0, 0];
|
||||
pub const Amount: [i8; 7] = [0, 0, 0, 0, 0, 1, 0];
|
||||
pub const Catalytic: [i8; 7] = [-1, 0, 0, 0, 0, 1, 0];
|
||||
pub const Intensity: [i8; 7] = [0, 0, 0, 0, 0, 0, 1];
|
||||
}
|
||||
|
||||
fn gen_units_list() -> HashMap<[i8; 7], Dimension> {
|
||||
use matricies::*;
|
||||
|
||||
const YEAR: f64 = 31_557_600.0;
|
||||
const DAY: f64 = 60.0 * 60.0 * 24.0;
|
||||
|
||||
hash_map!{
|
||||
Scalar => Dimension {
|
||||
name: "Scalar",
|
||||
units: vec![],
|
||||
},
|
||||
Time => Dimension {
|
||||
name: "Time",
|
||||
units:
|
||||
vec![
|
||||
("Second", (1.0, 0.0)),
|
||||
("Kalpa", (YEAR * 1e9 * 4.32, 0.0)),
|
||||
("Eon", (YEAR * 1e9, 0.0)),
|
||||
("GalacticYear", (YEAR * 2.3e8, 0.0)),
|
||||
("Age", (YEAR * (2148.0 + 1.0 / 3.0), 0.0)),
|
||||
("Millenium", (YEAR * 1000.0, 0.0)),
|
||||
("Centurie", (YEAR * 100.0, 0.0)),
|
||||
("Jubilee", (YEAR * 50.0, 0.0)),
|
||||
("Indiction", (YEAR * 15.0, 0.0)),
|
||||
("Decade", (YEAR * 10.0, 0.0)),
|
||||
("Lustrum", (YEAR * 5.0, 0.0)),
|
||||
("Olympiad", (YEAR * 4.0, 0.0)),
|
||||
("LeapYear", (YEAR + DAY, 0.0)),
|
||||
("LunarYear", (DAY * 354.37, 0.0)),
|
||||
("Semester", (DAY * 7.0 * 18.0, 0.0)),
|
||||
("Quarantine", (DAY * 40.0, 0.0)),
|
||||
("Month", (DAY * 30.0, 0.0)),
|
||||
("Fortnight", (DAY * 7.0, 0.0)),
|
||||
("Week", (60.0e2 * 24.0 * 7.0, 0.0)),
|
||||
("Milliday", (DAY * 0.001, 0.0)),
|
||||
("Day", (60.0e2 * 24.0, 0.0)),
|
||||
("Hour", (60.0e2, 0.0)),
|
||||
("Minute", (60.0, 0.0)),
|
||||
("Jiffy", (3e-24, 0.0)),
|
||||
("Shake", (1e-08, 0.0)),
|
||||
("PlanckTime", (5.39e-44, 0.0))
|
||||
]
|
||||
},
|
||||
Frequency => Dimension {
|
||||
name: "Frequency",
|
||||
units: vec![("Hertz", (1.0, 0.0)), ("Rpm", (1.0 / 60.0, 0.0))],
|
||||
},
|
||||
Length => Dimension {
|
||||
name: "Length",
|
||||
units:
|
||||
vec![
|
||||
("Meter", (1.0, 0.0)),
|
||||
("Planck", (1.6e-35, 0.0)),
|
||||
("Yard", (0.9144, 0.0)),
|
||||
("Feet", (0.3048, 0.0)),
|
||||
("Inche", (0.0254, 0.0)),
|
||||
("Angstrom", (10e-10, 0.0))
|
||||
],
|
||||
},
|
||||
Area => Dimension {
|
||||
name: "Area",
|
||||
units:
|
||||
vec![
|
||||
("SqMeter", (1.0, 0.0)),
|
||||
("SqPlanck", (1.6e-35, 0.0)),
|
||||
("SqYard", (0.9144, 0.0)),
|
||||
("SqInche", (0.0254, 0.0)),
|
||||
("SqAngstrom", (1e-10, 0.0))
|
||||
],
|
||||
},
|
||||
Speed => Dimension {
|
||||
name: "Speed",
|
||||
units: vec![("MetersPerSecond", (1.0, 0.0)), ("Kmph", (3_600.0, 0.0)), ("Mph", (2_237.0, 0.0))],
|
||||
},
|
||||
Acceleration => Dimension {
|
||||
name: "Acceleration",
|
||||
units: vec![("MetersPerSecondPerSecond", (1.0, 0.0)), ("Gee", (9.80665, 0.0))],
|
||||
},
|
||||
Mass => Dimension {
|
||||
name: "Mass",
|
||||
units: vec![("Gram", (1e-03, 0.0))],
|
||||
},
|
||||
MassPerDist => Dimension {
|
||||
name: "MassPerDist",
|
||||
units: vec![("KgPerMeter", (1.0, 0.0))],
|
||||
},
|
||||
Density => Dimension {
|
||||
name: "Density",
|
||||
units: vec![("KgPerCubicMeter", (1.0, 0.0))],
|
||||
},
|
||||
MassMoment => Dimension {
|
||||
name: "MassMoment",
|
||||
units: vec![("KgSqMeter", (1.0, 0.0))],
|
||||
},
|
||||
Force => Dimension {
|
||||
name: "Force",
|
||||
units: vec![("Newton", (1.0, 0.0))],
|
||||
},
|
||||
ForceMoment => Dimension {
|
||||
name: "ForceMoment",
|
||||
units: vec![("NewtonMeter", (1.0, 0.0))],
|
||||
},
|
||||
Pressure => Dimension {
|
||||
name: "Pressure",
|
||||
units: vec![("Pascal", (1.0, 0.0))],
|
||||
},
|
||||
Energy => Dimension {
|
||||
name: "Energy",
|
||||
units: vec![("Joule", (1.0, 0.0)), ("Watthour", (3600.0, 0.0))],
|
||||
},
|
||||
Power => Dimension {
|
||||
name: "Power",
|
||||
units: vec![("Watt", (1.0, 0.0))],
|
||||
},
|
||||
Current => Dimension {
|
||||
name: "Current",
|
||||
units: vec![("Amp", (1.0, 0.0))],
|
||||
},
|
||||
Charge => Dimension {
|
||||
name: "Charge",
|
||||
units: vec![("Coulomb", (1.0, 0.0))],
|
||||
},
|
||||
Potential => Dimension {
|
||||
name: "Potential",
|
||||
units: vec![("Volt", (1.0, 0.0))],
|
||||
},
|
||||
Capacitance => Dimension {
|
||||
name: "Capacitance",
|
||||
units: vec![("Farad", (1.0, 0.0))],
|
||||
},
|
||||
Resistance => Dimension {
|
||||
name: "Resistance",
|
||||
units: vec![("Ohm", (1.0, 0.0))],
|
||||
},
|
||||
Conductance => Dimension {
|
||||
name: "Conductance",
|
||||
units: vec![("Siemen", (1.0, 0.0))],
|
||||
},
|
||||
Flux => Dimension {
|
||||
name: "Flux",
|
||||
units: vec![("Weber", (1.0, 0.0))],
|
||||
},
|
||||
FluxDensity => Dimension {
|
||||
name: "FluxDensity",
|
||||
units: vec![("Tesla", (1.0, 0.0))],
|
||||
},
|
||||
Inductance => Dimension {
|
||||
name: "Inductance",
|
||||
units: vec![("Henry", (1.0, 0.0))],
|
||||
},
|
||||
Catalytic => Dimension {
|
||||
name: "Catalytic",
|
||||
units: vec![("Katal", (1.0, 0.0))],
|
||||
},
|
||||
Temperature => Dimension {
|
||||
name: "Temperature",
|
||||
units: vec![("Kelvin", (1.0, 0.0)), ("Celsius", (1.0, 273.15)), ("Fahrenheit", (5.0 / 9.0, 459.67))],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<i8> for Matrix {
|
||||
type Output = Matrix;
|
||||
fn div(self, rhs: i8) -> Self::Output {
|
||||
let mut output = Matrix::default();
|
||||
for (i, v) in self.0.iter().enumerate() {
|
||||
output.0[i] = v / rhs;
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Matrix {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
let mut output = Matrix::default();
|
||||
for (i, (a, b)) in self.0.iter().zip(&rhs.0).enumerate() {
|
||||
output.0[i] = a + b;
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Matrix {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
let mut output = Matrix::default();
|
||||
for (i, (a, b)) in self.0.iter().zip(&rhs.0).enumerate() {
|
||||
output.0[i] = a - b;
|
||||
}
|
||||
output
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_convert(dimension: &str) -> TokenStream {
|
||||
let dim_ident = format_ident!["{dimension}"];
|
||||
if dimension == "Scalar" {
|
||||
quote! {
|
||||
pub fn new(v: f64) -> Self {
|
||||
Self(v)
|
||||
}
|
||||
pub fn val(self) -> f64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
pub fn new<T: Scale<#dim_ident>>(v: f64) -> Self {
|
||||
Self(v * T::scale().0 + T::scale().1)
|
||||
}
|
||||
pub fn val<T: Scale<#dim_ident>>(self) -> f64 {
|
||||
(self.0 - T::scale().1) / T::scale().0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_simple_traits(unit: &str) -> TokenStream {
|
||||
let unit = format_ident!["{unit}"];
|
||||
quote! {
|
||||
impl Add for #unit {
|
||||
type Output = #unit;
|
||||
fn add(self, rhs: #unit) -> Self::Output {
|
||||
#unit(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
impl Sub for #unit {
|
||||
type Output = #unit;
|
||||
fn sub(self, rhs: #unit) -> Self::Output {
|
||||
#unit(self.0 - rhs.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_mul(lhs: &str, rhs: &str, output: &str) -> TokenStream {
|
||||
let lhs = format_ident!["{lhs}"];
|
||||
let rhs = format_ident!["{rhs}"];
|
||||
let output = format_ident!["{output}"];
|
||||
quote! {
|
||||
impl Mul<#rhs> for #lhs {
|
||||
type Output = #output;
|
||||
fn mul(self, rhs: #rhs) -> Self::Output {
|
||||
#output(self.0 * rhs.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_div(lhs: &str, rhs: &str, output: &str) -> TokenStream {
|
||||
let lhs = format_ident!["{lhs}"];
|
||||
let rhs = format_ident!["{rhs}"];
|
||||
let output = format_ident!["{output}"];
|
||||
quote! {
|
||||
impl Div<#rhs> for #lhs {
|
||||
type Output = #output;
|
||||
fn div(self, rhs: #rhs) -> Self::Output {
|
||||
#output(self.0 / rhs.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_unit_structs(units_list: &[(&str, (f64, f64))], dimension: &str) -> TokenStream {
|
||||
let dim_ident = format_ident!["{dimension}"];
|
||||
let mut units = quote! {};
|
||||
for (nym, (scale, offset)) in units_list {
|
||||
let ident = format_ident!["{nym}"];
|
||||
units.extend(quote! {
|
||||
pub struct #ident;
|
||||
impl Scale<#dim_ident> for #ident {
|
||||
fn scale() -> (f64, f64) {
|
||||
(#scale, #offset)
|
||||
fn gen_units() -> (TokenStream, TokenStream) {
|
||||
let dimensions = gen_units_list();
|
||||
let mut dimension_decls = quote!{
|
||||
};
|
||||
let mut unit_decls = quote!{
|
||||
};
|
||||
for (matrix, Dimension { name: basename, units }) in dimensions.iter() {
|
||||
let time = matrix[0];
|
||||
let length = matrix[0];
|
||||
let mass = matrix[0];
|
||||
let current = matrix[0];
|
||||
let temperature = matrix[0];
|
||||
let amount = matrix[0];
|
||||
let intensity = matrix[0];
|
||||
let unit_type = quote!{
|
||||
Measurement < #time,
|
||||
#length,
|
||||
#mass,
|
||||
#current,
|
||||
#temperature,
|
||||
#amount,
|
||||
#intensity >
|
||||
};
|
||||
let unit_type_path = quote!{
|
||||
Measurement::< #time,
|
||||
#length,
|
||||
#mass,
|
||||
#current,
|
||||
#temperature,
|
||||
#amount,
|
||||
#intensity >
|
||||
};
|
||||
let basename_ident = format_ident!["{basename}"];
|
||||
dimension_decls.extend(quote!{
|
||||
pub type #basename_ident = #unit_type;
|
||||
});
|
||||
for (unit_nym, (scale, offset)) in units {
|
||||
let ident = format_ident!["{unit_nym}"];
|
||||
unit_decls.extend(quote!{
|
||||
pub struct #ident;
|
||||
impl Unit < #unit_type > for #ident {
|
||||
fn new(v: f64) -> #unit_type {
|
||||
#unit_type_path:: new::< Self >(v)
|
||||
}
|
||||
fn scale() -> f64 {
|
||||
#scale
|
||||
}
|
||||
fn offset() -> f64 {
|
||||
#offset
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
units
|
||||
(dimension_decls, unit_decls)
|
||||
}
|
||||
|
||||
fn gen_prefixes() -> TokenStream {
|
||||
let mut prefixes = quote! {};
|
||||
for (nym, scale) in [
|
||||
let mut prefix_decls = quote!{
|
||||
use std::marker::PhantomData;
|
||||
};
|
||||
for (
|
||||
nym,
|
||||
scale,
|
||||
) in [
|
||||
("Quetta", 1e30),
|
||||
("Ronna", 1e27),
|
||||
("Yotta", 1e24),
|
||||
|
@ -170,485 +301,93 @@ fn gen_prefixes() -> TokenStream {
|
|||
("Quecto", 1e-30),
|
||||
] {
|
||||
let ident = format_ident!["{nym}"];
|
||||
prefixes.extend(quote! {
|
||||
pub struct #ident<T>(PhantomData<T>);
|
||||
impl<T: Scale<D>, D> Scale<D> for #ident<T> {
|
||||
fn scale() -> (f64, f64) {
|
||||
(#scale * T::scale().0, T::scale().1)
|
||||
prefix_decls.extend(quote!{
|
||||
pub struct #ident < T >(PhantomData < T >);
|
||||
impl < const TIME: i8,
|
||||
const LENGTH: i8,
|
||||
const MASS: i8,
|
||||
const CHARGE: i8,
|
||||
const TEMPERATURE: i8,
|
||||
const AMOUNT: i8,
|
||||
const INTENSITY: i8,
|
||||
T: Unit < Measurement < TIME,
|
||||
LENGTH,
|
||||
MASS,
|
||||
CHARGE,
|
||||
TEMPERATURE,
|
||||
AMOUNT,
|
||||
INTENSITY >>,
|
||||
> Unit < Measurement < TIME,
|
||||
LENGTH,
|
||||
MASS,
|
||||
CHARGE,
|
||||
TEMPERATURE,
|
||||
AMOUNT,
|
||||
INTENSITY >> for #ident < T > {
|
||||
fn new(v: f64) -> Measurement < TIME,
|
||||
LENGTH,
|
||||
MASS,
|
||||
CHARGE,
|
||||
TEMPERATURE,
|
||||
AMOUNT,
|
||||
INTENSITY > {
|
||||
Measurement::<TIME, LENGTH, MASS, CHARGE, TEMPERATURE, AMOUNT, INTENSITY>::new::<Self>(v)
|
||||
}
|
||||
fn scale() -> f64 {
|
||||
#scale * T:: scale()
|
||||
}
|
||||
fn offset() -> f64 {
|
||||
T::offset()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
prefixes
|
||||
}
|
||||
|
||||
struct Dimension {
|
||||
basename: &'static str,
|
||||
conversions: Vec<(&'static str, (f64, f64))>,
|
||||
prefix_decls
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("units.rs");
|
||||
let dimensions: HashMap<Matrix, Dimension> = gen_units_list();
|
||||
let mut code = quote! {
|
||||
pub trait Scale<D> {
|
||||
fn scale() -> (f64, f64);
|
||||
let mut code = quote!{
|
||||
pub trait Unit<D> {
|
||||
fn new(v: f64) -> D;
|
||||
fn scale() -> f64;
|
||||
fn offset() -> f64;
|
||||
}
|
||||
};
|
||||
let prefixes = gen_prefixes();
|
||||
let prefixes_mod = quote! {
|
||||
pub mod prefixes {
|
||||
use crate::Scale;
|
||||
use core::marker::PhantomData;
|
||||
#prefixes
|
||||
}
|
||||
};
|
||||
code.extend(prefixes_mod);
|
||||
let mut dims_mod = quote! {};
|
||||
let mut units_mod = quote! {};
|
||||
for (
|
||||
matrix,
|
||||
Dimension {
|
||||
basename,
|
||||
conversions: subunits,
|
||||
},
|
||||
) in dimensions.iter()
|
||||
{
|
||||
let basename_ident = format_ident!["{basename}"];
|
||||
let decl = quote! {
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct #basename_ident(f64);
|
||||
impl Mul<f64> for #basename_ident {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: f64) -> Self::Output {
|
||||
Self(self.0 * rhs)
|
||||
}
|
||||
}
|
||||
impl Mul<#basename_ident> for f64 {
|
||||
type Output = #basename_ident;
|
||||
fn mul(self, rhs: #basename_ident) -> Self::Output {
|
||||
#basename_ident(self * rhs.0)
|
||||
}
|
||||
}
|
||||
impl Div<f64> for #basename_ident {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: f64) -> Self::Output {
|
||||
Self(self.0 / rhs)
|
||||
}
|
||||
}
|
||||
impl Div<#basename_ident> for f64 {
|
||||
type Output = #basename_ident;
|
||||
fn div(self, rhs: #basename_ident) -> Self::Output {
|
||||
#basename_ident(self * rhs.0)
|
||||
}
|
||||
}
|
||||
};
|
||||
dims_mod.extend(decl);
|
||||
let mut exponentiation = quote! {};
|
||||
for (method_name, n) in [
|
||||
("square", 2),
|
||||
("cube", 3),
|
||||
("square_root", -2),
|
||||
("cube_root", -3),
|
||||
] {
|
||||
if n == 0 {
|
||||
continue;
|
||||
}
|
||||
let matrix = if n > 0 {
|
||||
*matrix * n
|
||||
} else {
|
||||
if matrix.0.iter().fold(false, |a, v| a || (v % n.abs() != 0)) {
|
||||
continue;
|
||||
}
|
||||
*matrix / n.abs()
|
||||
let (dimensions, units) = gen_units();
|
||||
let modules = quote!{
|
||||
pub mod prelude {
|
||||
pub use crate::units::{
|
||||
Gram,
|
||||
Hour,
|
||||
Meter,
|
||||
MetersPerSecond,
|
||||
MetersPerSecondPerSecond,
|
||||
Second,
|
||||
};
|
||||
pub use crate::{
|
||||
Centi,
|
||||
Kilo,
|
||||
Micro,
|
||||
Milli,
|
||||
Nano,
|
||||
};
|
||||
if let Some(derived) = dimensions.get(&matrix) {
|
||||
let ident = format_ident!["{method_name}"];
|
||||
let derived_ident = format_ident!["{}", derived.basename];
|
||||
exponentiation.extend(if n > 0 {
|
||||
quote! {
|
||||
pub fn #ident(self) -> #derived_ident {
|
||||
#derived_ident(self.0.powf(#n.abs() as f64))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
pub fn #ident(self) -> #derived_ident {
|
||||
#derived_ident(self.0.powf(1.0 / (#n.abs() as f64)))
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
let mut conversion = quote! {};
|
||||
conversion.extend(impl_convert(basename));
|
||||
dims_mod.extend(quote! {
|
||||
impl #basename_ident {
|
||||
#exponentiation
|
||||
#conversion
|
||||
}
|
||||
});
|
||||
dims_mod.extend(impl_simple_traits(basename));
|
||||
if let Some(derived) = dimensions.get(&(*matrix + *matrix)) {
|
||||
dims_mod.extend(impl_mul(basename, basename, derived.basename));
|
||||
}
|
||||
if let Some(derived) = dimensions.get(&(*matrix - *matrix)) {
|
||||
dims_mod.extend(impl_div(basename, basename, derived.basename));
|
||||
}
|
||||
for (
|
||||
other_matrix,
|
||||
Dimension {
|
||||
basename: other_basename,
|
||||
..
|
||||
},
|
||||
) in dimensions.iter()
|
||||
{
|
||||
if matrix == other_matrix {
|
||||
continue;
|
||||
}
|
||||
if let Some(derived) = dimensions.get(&(*matrix + *other_matrix)) {
|
||||
dims_mod.extend(impl_mul(basename, other_basename, derived.basename));
|
||||
}
|
||||
if let Some(derived) = dimensions.get(&(*matrix - *other_matrix)) {
|
||||
dims_mod.extend(impl_div(basename, other_basename, derived.basename));
|
||||
}
|
||||
}
|
||||
let submod_ident = format_ident!["{}", basename.to_lowercase()];
|
||||
let unit_structs = gen_unit_structs(subunits, basename);
|
||||
units_mod.extend(quote! {
|
||||
pub mod #submod_ident {
|
||||
use crate::Scale;
|
||||
use crate::dimensions::#basename_ident;
|
||||
#unit_structs
|
||||
}
|
||||
pub use #submod_ident::*;
|
||||
});
|
||||
}
|
||||
code.extend(quote! {
|
||||
pub mod dimensions {
|
||||
use crate::Scale;
|
||||
use std::ops::{Add, Div, Mul, Sub};
|
||||
#dims_mod
|
||||
use crate::Measurement;
|
||||
#dimensions
|
||||
}
|
||||
pub mod units {
|
||||
#units_mod
|
||||
use crate::{
|
||||
Measurement,
|
||||
Unit,
|
||||
};
|
||||
#units
|
||||
}
|
||||
});
|
||||
File::create(&dest_path)
|
||||
.unwrap()
|
||||
.write_all(code.to_string().as_bytes())
|
||||
.unwrap();
|
||||
|
||||
};
|
||||
code.extend(modules);
|
||||
code.extend(gen_prefixes());
|
||||
File::create(&dest_path).unwrap().write_all(code.to_string().as_bytes()).unwrap();
|
||||
println!["cargo:rerun-if-changed=build.rs"];
|
||||
}
|
||||
#[rustfmt::skip]
|
||||
mod matricies {
|
||||
use super::Matrix;
|
||||
pub const Scalar: Matrix = Matrix([ 0, 0, 0, 0, 0, 0, 0]);
|
||||
pub const Time: Matrix = Matrix([ 1, 0, 0, 0, 0, 0, 0]);
|
||||
pub const Frequency: Matrix = Matrix([-1, 0, 0, 0, 0, 0, 0]);
|
||||
pub const Tempoflux: Matrix = Matrix([-2, 0, 0, 0, 0, 0, 0]);
|
||||
pub const Length: Matrix = Matrix([ 0, 1, 0, 0, 0, 0, 0]);
|
||||
pub const Area: Matrix = Matrix([ 0, 2, 0, 0, 0, 0, 0]);
|
||||
pub const Speed: Matrix = Matrix([-1, 1, 0, 0, 0, 0, 0]);
|
||||
pub const SquareSpeed: Matrix = Matrix([-2, 2, 0, 0, 0, 0, 0]);
|
||||
pub const Acceleration: Matrix = Matrix([-2, 1, 0, 0, 0, 0, 0]);
|
||||
pub const Mass: Matrix = Matrix([ 0, 0, 1, 0, 0, 0, 0]);
|
||||
pub const MassPerSqTime: Matrix = Matrix([-2, 0, 1, 0, 0, 0, 0]);
|
||||
pub const MassPerDist: Matrix = Matrix([ 0,-1, 1, 0, 0, 0, 0]);
|
||||
pub const Dispersion: Matrix = Matrix([ 0,-2, 1, 0, 0, 0, 0]);
|
||||
pub const Density: Matrix = Matrix([ 0,-3, 1, 0, 0, 0, 0]);
|
||||
pub const MassMoment: Matrix = Matrix([ 0, 2, 1, 0, 0, 0, 0]);
|
||||
pub const Force: Matrix = Matrix([-2, 1, 1, 0, 0, 0, 0]);
|
||||
pub const ForceMoment: Matrix = Matrix([-2, 2, 1, 0, 0, 0, 0]);
|
||||
pub const Pressure: Matrix = Matrix([-2,-1, 1, 0, 0, 0, 0]);
|
||||
pub const Energy: Matrix = Matrix([-2, 2, 1, 0, 0, 0, 0]);
|
||||
pub const Power: Matrix = Matrix([-3, 2, 1, 0, 0, 0, 0]);
|
||||
pub const Current: Matrix = Matrix([ 0, 0, 0, 1, 0, 0, 0]);
|
||||
pub const Charge: Matrix = Matrix([ 1, 0, 0, 1, 0, 0, 0]);
|
||||
pub const Capacitance: Matrix = Matrix([ 4,-2,-1, 1, 0, 0, 0]);
|
||||
pub const Potential: Matrix = Matrix([-3,-2, 1,-1, 0, 0, 0]);
|
||||
pub const Resistance: Matrix = Matrix([-3, 2, 1,-2, 0, 0, 0]);
|
||||
pub const Conductance: Matrix = Matrix([ 3,-2,-1, 2, 0, 0, 0]);
|
||||
pub const Flux: Matrix = Matrix([-2, 2, 1,-1, 0, 0, 0]);
|
||||
pub const FluxDensity: Matrix = Matrix([ 2, 0, 1,-1, 0, 0, 0]);
|
||||
pub const Inductance: Matrix = Matrix([-2, 2, 1,-2, 0, 0, 0]);
|
||||
pub const Temperature: Matrix = Matrix([ 0, 0, 0, 0, 1, 0, 0]);
|
||||
pub const Amount: Matrix = Matrix([ 0, 0, 0, 0, 0, 1, 0]);
|
||||
pub const Catalytic: Matrix = Matrix([-1, 0, 0, 0, 0, 1, 0]);
|
||||
pub const Intensity: Matrix = Matrix([ 0, 0, 0, 0, 0, 0, 1]);
|
||||
}
|
||||
use matricies::*;
|
||||
|
||||
fn gen_units_list() -> HashMap<Matrix, Dimension> {
|
||||
let mut output = HashMap::new();
|
||||
const YEAR: f64 = 31_557_600.0;
|
||||
const DAY: f64 = 60.0 * 60.0 * 24.0;
|
||||
output.insert(
|
||||
Scalar,
|
||||
Dimension {
|
||||
basename: "Scalar",
|
||||
conversions: vec![],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Time,
|
||||
Dimension {
|
||||
basename: "Time",
|
||||
conversions: vec![
|
||||
("Seconds", (1.0, 0.0)),
|
||||
("Kalpas", (YEAR * 1e9 * 4.32, 0.0)),
|
||||
("Eons", (YEAR * 1e9, 0.0)),
|
||||
("GalacticYears", (YEAR * 2.3e8, 0.0)),
|
||||
("Ages", (YEAR * (2148.0 + 1.0 / 3.0), 0.0)),
|
||||
("Milleniums", (YEAR * 1000.0, 0.0)),
|
||||
("Centuries", (YEAR * 100.0, 0.0)),
|
||||
("Jubilees", (YEAR * 50.0, 0.0)),
|
||||
("Indictions", (YEAR * 15.0, 0.0)),
|
||||
("Decades", (YEAR * 10.0, 0.0)),
|
||||
("Lustrums", (YEAR * 5.0, 0.0)),
|
||||
("Olympiads", (YEAR * 4.0, 0.0)),
|
||||
("LeapYears", (YEAR + DAY, 0.0)),
|
||||
("LunarYears", (DAY * 354.37, 0.0)),
|
||||
("Semesters", (DAY * 7.0 * 18.0, 0.0)),
|
||||
("Quarantines", (DAY * 40.0, 0.0)),
|
||||
("Months", (DAY * 30.0, 0.0)),
|
||||
("Fortnights", (DAY * 7.0, 0.0)),
|
||||
("Weeks", (60.0e2 * 24.0 * 7.0, 0.0)),
|
||||
("Millidays", (DAY * 0.001, 0.0)),
|
||||
("Days", (60.0e2 * 24.0, 0.0)),
|
||||
("Hours", (60.0e2, 0.0)),
|
||||
("Minutes", (60.0, 0.0)),
|
||||
("Jiffys", (3e-24, 0.0)),
|
||||
("Shakes", (1e-08, 0.0)),
|
||||
("PlanckTimes", (5.39e-44, 0.0)),
|
||||
],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Frequency,
|
||||
Dimension {
|
||||
basename: "Frequency",
|
||||
conversions: vec![("Hertz", (1.0, 0.0)), ("Rpm", (1.0 / 60.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Tempoflux,
|
||||
Dimension {
|
||||
basename: "Tempoflux",
|
||||
conversions: vec![("SqHertz", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Length,
|
||||
Dimension {
|
||||
basename: "Length",
|
||||
conversions: vec![
|
||||
("Meters", (1.0, 0.0)),
|
||||
("Plancks", (1.6e-35, 0.0)),
|
||||
("Yards", (0.9144, 0.0)),
|
||||
("Feet", (0.3048, 0.0)),
|
||||
("Inches", (0.0254, 0.0)),
|
||||
("Angstroms", (10e-10, 0.0)),
|
||||
],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Area,
|
||||
Dimension {
|
||||
basename: "Area",
|
||||
conversions: vec![
|
||||
("SqMeters", (1.0, 0.0)),
|
||||
("SqPlancks", (1.6e-35, 0.0)),
|
||||
("SqYards", (0.9144, 0.0)),
|
||||
("SqInches", (0.0254, 0.0)),
|
||||
("SqAngstroms", (1e-10, 0.0)),
|
||||
],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Speed,
|
||||
Dimension {
|
||||
basename: "Speed",
|
||||
conversions: vec![
|
||||
("MetersPerSecond", (1.0, 0.0)),
|
||||
("Kmph", (3_600.0, 0.0)),
|
||||
("Mph", (2_237.0, 0.0)),
|
||||
],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
SquareSpeed,
|
||||
Dimension {
|
||||
basename: "SquareSpeed",
|
||||
conversions: vec![("SqMetersPerSqTime", (2_237.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Acceleration,
|
||||
Dimension {
|
||||
basename: "Acceleration",
|
||||
conversions: vec![("MetersPerSqTime", (1.0, 0.0)), ("Gees", (9.80665, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Mass,
|
||||
Dimension {
|
||||
basename: "Mass",
|
||||
conversions: vec![("Grams", (1e-03, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
MassPerSqTime,
|
||||
Dimension {
|
||||
basename: "MassPerSqTime",
|
||||
conversions: vec![("GramsPerS2", (1e-03, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
MassPerDist,
|
||||
Dimension {
|
||||
basename: "MassPerDist",
|
||||
conversions: vec![("KgPerMeter", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Dispersion,
|
||||
Dimension {
|
||||
basename: "Dispersion",
|
||||
conversions: vec![("KgPerSqMeter", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Density,
|
||||
Dimension {
|
||||
basename: "Density",
|
||||
conversions: vec![("KgPerCubicMeter", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
MassMoment,
|
||||
Dimension {
|
||||
basename: "MassMoment",
|
||||
conversions: vec![("KgSqMeters", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Force,
|
||||
Dimension {
|
||||
basename: "Force",
|
||||
conversions: vec![("Newtons", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
ForceMoment,
|
||||
Dimension {
|
||||
basename: "ForceMoment",
|
||||
conversions: vec![("NewtonMeters", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Pressure,
|
||||
Dimension {
|
||||
basename: "Pressure",
|
||||
conversions: vec![("Pascals", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Energy,
|
||||
Dimension {
|
||||
basename: "Energy",
|
||||
conversions: vec![("Joules", (1.0, 0.0)), ("Watthours", (3600.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Power,
|
||||
Dimension {
|
||||
basename: "Power",
|
||||
conversions: vec![("Watts", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Current,
|
||||
Dimension {
|
||||
basename: "Current",
|
||||
conversions: vec![("Amps", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Charge,
|
||||
Dimension {
|
||||
basename: "Charge",
|
||||
conversions: vec![("Coulombs", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Potential,
|
||||
Dimension {
|
||||
basename: "Potential",
|
||||
conversions: vec![("Volts", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Capacitance,
|
||||
Dimension {
|
||||
basename: "Capacitance",
|
||||
conversions: vec![("Farads", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Resistance,
|
||||
Dimension {
|
||||
basename: "Resistance",
|
||||
conversions: vec![("Ohms", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Conductance,
|
||||
Dimension {
|
||||
basename: "Conductance",
|
||||
conversions: vec![("Siemens", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Flux,
|
||||
Dimension {
|
||||
basename: "Flux",
|
||||
conversions: vec![("Webers", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
FluxDensity,
|
||||
Dimension {
|
||||
basename: "FluxDensity",
|
||||
conversions: vec![("Teslas", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Inductance,
|
||||
Dimension {
|
||||
basename: "Inductance",
|
||||
conversions: vec![("Henrys", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Catalytic,
|
||||
Dimension {
|
||||
basename: "Catalytic",
|
||||
conversions: vec![("Katals", (1.0, 0.0))],
|
||||
},
|
||||
);
|
||||
output.insert(
|
||||
Temperature,
|
||||
Dimension {
|
||||
basename: "Temperature",
|
||||
conversions: vec![
|
||||
("Kelvin", (1.0, 0.0)),
|
||||
("Celsius", (1.0, 273.15)),
|
||||
("Fahrenheit", (5.0 / 9.0, 459.67)),
|
||||
],
|
||||
},
|
||||
);
|
||||
output
|
||||
}
|
||||
|
|
227
src/lib.rs
227
src/lib.rs
|
@ -1 +1,226 @@
|
|||
include!(concat!(env!("OUT_DIR"), "/units.rs"));
|
||||
#![feature(generic_const_exprs)]
|
||||
|
||||
include![concat![env!["OUT_DIR"], "/units.rs"]];
|
||||
|
||||
pub use units::*;
|
||||
use std::ops::{
|
||||
Add,
|
||||
Div,
|
||||
Mul,
|
||||
Sub,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Measurement<
|
||||
const TIME: i8,
|
||||
const LENGTH: i8,
|
||||
const MASS: i8,
|
||||
const CURRENT: i8,
|
||||
const TEMPERATURE: i8,
|
||||
const AMOUNT: i8,
|
||||
const INTENSITY: i8,
|
||||
>(
|
||||
f64,
|
||||
);
|
||||
|
||||
impl<
|
||||
const TIME: i8,
|
||||
const LENGTH: i8,
|
||||
const MASS: i8,
|
||||
const CURRENT: i8,
|
||||
const TEMPERATURE: i8,
|
||||
const AMOUNT: i8,
|
||||
const INTENSITY: i8,
|
||||
> Measurement<TIME, LENGTH, MASS, CURRENT, TEMPERATURE, AMOUNT, INTENSITY> {
|
||||
pub fn new<U>(v: f64) -> Self
|
||||
where
|
||||
U: Unit<Self> {
|
||||
Self(v.mul(U::scale()).add(U::offset()))
|
||||
}
|
||||
|
||||
pub fn to_units<U>(self) -> f64
|
||||
where
|
||||
U: Unit<Self> {
|
||||
self.0.sub(U::offset()).div(U::scale())
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
const A_TIME: i8,
|
||||
const A_LENGTH: i8,
|
||||
const A_MASS: i8,
|
||||
const A_CURRENT: i8,
|
||||
const A_TEMPERATURE: i8,
|
||||
const A_AMOUNT: i8,
|
||||
const A_INTENSITY: i8,
|
||||
const B_TIME: i8,
|
||||
const B_LENGTH: i8,
|
||||
const B_MASS: i8,
|
||||
const B_CURRENT: i8,
|
||||
const B_TEMPERATURE: i8,
|
||||
const B_AMOUNT: i8,
|
||||
const B_INTENSITY: i8,
|
||||
> Mul<
|
||||
Measurement<B_TIME, B_LENGTH, B_MASS, B_CURRENT, B_TEMPERATURE, B_AMOUNT, B_INTENSITY>,
|
||||
> for Measurement<A_TIME, A_LENGTH, A_MASS, A_CURRENT, A_TEMPERATURE, A_AMOUNT, A_INTENSITY>
|
||||
where
|
||||
Measurement<{
|
||||
A_TIME + B_TIME
|
||||
}, {
|
||||
A_LENGTH + B_LENGTH
|
||||
}, {
|
||||
A_MASS + B_MASS
|
||||
}, {
|
||||
A_CURRENT + B_CURRENT
|
||||
}, {
|
||||
A_TEMPERATURE + B_TEMPERATURE
|
||||
}, {
|
||||
A_AMOUNT + B_AMOUNT
|
||||
}, {
|
||||
A_INTENSITY + B_INTENSITY
|
||||
}>: Sized {
|
||||
type Output = Measurement<{
|
||||
A_TIME + B_TIME
|
||||
}, {
|
||||
A_LENGTH + B_LENGTH
|
||||
}, {
|
||||
A_MASS + B_MASS
|
||||
}, {
|
||||
A_CURRENT + B_CURRENT
|
||||
}, {
|
||||
A_TEMPERATURE + B_TEMPERATURE
|
||||
}, {
|
||||
A_AMOUNT + B_AMOUNT
|
||||
}, {
|
||||
A_INTENSITY + B_INTENSITY
|
||||
}>;
|
||||
|
||||
fn mul(
|
||||
self,
|
||||
rhs: Measurement<B_TIME, B_LENGTH, B_MASS, B_CURRENT, B_TEMPERATURE, B_AMOUNT, B_INTENSITY>,
|
||||
) -> Self::Output {
|
||||
Measurement::<{
|
||||
A_TIME + B_TIME
|
||||
}, {
|
||||
A_LENGTH + B_LENGTH
|
||||
}, {
|
||||
A_MASS + B_MASS
|
||||
}, {
|
||||
A_CURRENT + B_CURRENT
|
||||
}, {
|
||||
A_TEMPERATURE + B_TEMPERATURE
|
||||
}, {
|
||||
A_AMOUNT + B_AMOUNT
|
||||
}, {
|
||||
A_INTENSITY + B_INTENSITY
|
||||
}>(self.0 * rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
const A_TIME: i8,
|
||||
const A_LENGTH: i8,
|
||||
const A_MASS: i8,
|
||||
const A_CURRENT: i8,
|
||||
const A_TEMPERATURE: i8,
|
||||
const A_AMOUNT: i8,
|
||||
const A_INTENSITY: i8,
|
||||
const B_TIME: i8,
|
||||
const B_LENGTH: i8,
|
||||
const B_MASS: i8,
|
||||
const B_CURRENT: i8,
|
||||
const B_TEMPERATURE: i8,
|
||||
const B_AMOUNT: i8,
|
||||
const B_INTENSITY: i8,
|
||||
> Div<
|
||||
Measurement<B_TIME, B_LENGTH, B_MASS, B_CURRENT, B_TEMPERATURE, B_AMOUNT, B_INTENSITY>,
|
||||
> for Measurement<A_TIME, A_LENGTH, A_MASS, A_CURRENT, A_TEMPERATURE, A_AMOUNT, A_INTENSITY>
|
||||
where
|
||||
Measurement<{
|
||||
A_TIME + B_TIME
|
||||
}, {
|
||||
A_LENGTH + B_LENGTH
|
||||
}, {
|
||||
A_MASS + B_MASS
|
||||
}, {
|
||||
A_CURRENT + B_CURRENT
|
||||
}, {
|
||||
A_TEMPERATURE + B_TEMPERATURE
|
||||
}, {
|
||||
A_AMOUNT + B_AMOUNT
|
||||
}, {
|
||||
A_INTENSITY + B_INTENSITY
|
||||
}>: Sized {
|
||||
type Output = Measurement<{
|
||||
A_TIME + B_TIME
|
||||
}, {
|
||||
A_LENGTH + B_LENGTH
|
||||
}, {
|
||||
A_MASS + B_MASS
|
||||
}, {
|
||||
A_CURRENT + B_CURRENT
|
||||
}, {
|
||||
A_TEMPERATURE + B_TEMPERATURE
|
||||
}, {
|
||||
A_AMOUNT + B_AMOUNT
|
||||
}, {
|
||||
A_INTENSITY + B_INTENSITY
|
||||
}>;
|
||||
|
||||
fn div(
|
||||
self,
|
||||
rhs: Measurement<B_TIME, B_LENGTH, B_MASS, B_CURRENT, B_TEMPERATURE, B_AMOUNT, B_INTENSITY>,
|
||||
) -> Self::Output {
|
||||
Measurement::<{
|
||||
A_TIME + B_TIME
|
||||
}, {
|
||||
A_LENGTH + B_LENGTH
|
||||
}, {
|
||||
A_MASS + B_MASS
|
||||
}, {
|
||||
A_CURRENT + B_CURRENT
|
||||
}, {
|
||||
A_TEMPERATURE + B_TEMPERATURE
|
||||
}, {
|
||||
A_AMOUNT + B_AMOUNT
|
||||
}, {
|
||||
A_INTENSITY + B_INTENSITY
|
||||
}>(self.0 / rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
const TIME: i8,
|
||||
const LENGTH: i8,
|
||||
const MASS: i8,
|
||||
const CURRENT: i8,
|
||||
const TEMPERATURE: i8,
|
||||
const AMOUNT: i8,
|
||||
const INTENSITY: i8,
|
||||
> Add for Measurement<TIME, LENGTH, MASS, CURRENT, TEMPERATURE, AMOUNT, INTENSITY>
|
||||
where
|
||||
Self: Sized {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
const TIME: i8,
|
||||
const LENGTH: i8,
|
||||
const MASS: i8,
|
||||
const CURRENT: i8,
|
||||
const TEMPERATURE: i8,
|
||||
const AMOUNT: i8,
|
||||
const INTENSITY: i8,
|
||||
> Sub for Measurement<TIME, LENGTH, MASS, CURRENT, TEMPERATURE, AMOUNT, INTENSITY>
|
||||
where
|
||||
Self: Sized {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self(self.0 - rhs.0)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue