use super::traits::*;
mod serde;
mod per_unit;
mod unit_div;
mod unit_mul;
mod unit_pow;
pub use per_unit::PerUnit;
pub use unit_div::UnitDiv;
pub use unit_mul::UnitMul;
pub use unit_pow::*;
mod impl_ops {
use core::ops::{Div, Mul};
use num_traits::Inv;
use typenum::Integer;
use crate::{dimension::*, units::compound::*};
macro_rules! impl_div_mul {
($($name:ident $(<$(
$param:ident $(: $bound:ident)?
),*>)?),* $(,)?) => {
$(impl<$($($param $(: $bound)?,)*)? __W: Unit>
Div<__W> for $name$(<$($param),*>)? where Self: CanUnitDiv<__W> {
type Output = UnitDiv<Self, __W>;
fn div(self, rhs: __W) -> Self::Output {
Self::Output::new(self, rhs)
}
})*
$(impl<$($($param $(: $bound)?,)*)? __W: Unit>
Mul<__W> for $name$(<$($param),*>)? where Self: CanUnitMul<__W> {
type Output = UnitMul<Self, __W>;
fn mul(self, rhs: __W) -> Self::Output {
Self::Output::new(self, rhs)
}
})*
};
}
impl_div_mul!(
PerUnit<U: Unit>,
UnitDiv<A: Unit, B: Unit>,
UnitMul<A: Unit, B: Unit>,
UnitPow<U: Unit, E: Integer>,
);
macro_rules! impl_inv {
($($name:ident $(<$(
$param:ident $(: $bound:ident)?
),*>)?),* $(,)?) => {
$(impl$(<$($param $(: $bound)?),*>)?
Inv for $name$(<$($param),*>)? where Self: CanUnitInv {
type Output = PerUnit<Self>;
fn inv(self) -> Self::Output {
Self::Output::new(self)
}
})*
};
}
impl_inv!(
PerUnit<U: Unit>,
UnitMul<A: Unit, B: Unit>,
UnitPow<U: Unit, E: Integer>,
);
impl<A: Unit, B: Unit> Inv for UnitDiv<A, B> {
type Output = UnitDiv<B, A>;
fn inv(self) -> Self::Output {
Self::Output::new(self.1, self.0)
}
}
macro_rules! impl_pow {
($($name:ident $(<$(
$param:ident $(: $bound:ident)?
),*>)?),* $(,)?) => {
$(impl<$($($param $(: $bound)?,)*)? const __E: i32>
CanPow<__E> for $name$(<$($param),*>)? where
Exponent<__E>: HasTypenum,
Self: Unit,
Self::Dim: CanDimPowType<<Exponent<__E> as HasTypenum>::Typenum>,
{
type Output = UnitPowN<Self, __E>;
fn pow(self) -> Self::Output {
Self::Output::new(self)
}
})*
};
}
impl_pow!(
PerUnit<U: Unit>,
UnitDiv<A: Unit, B: Unit>,
UnitMul<A: Unit, B: Unit>,
);
}