extern crate alloc;
use crate::{Length, Speed, length, time::Unit};
use core::fmt;
use core::marker::PhantomData;
use core::ops::{Add, Div, Mul, Sub};
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct Period<U>
where
U: Unit,
{
pub quantity: f64,
unit: PhantomData<U>,
}
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct Frequency<U>
where
U: Unit,
{
pub quantity: f64,
unit: PhantomData<U>,
}
impl_base_ops!(Period, Unit);
impl_base_ops!(Frequency, Unit);
impl<U> fmt::Display for Period<U>
where
U: Unit,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.quantity.fmt(f)?;
write!(f, " {}", U::LABEL)
}
}
impl<U> fmt::Display for Frequency<U>
where
U: Unit,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.quantity.fmt(f)?;
write!(f, " {}", U::INVERSE)
}
}
impl<U> Period<U>
where
U: Unit,
{
pub fn new(quantity: f64) -> Self {
Period::<U> {
quantity,
unit: PhantomData,
}
}
pub fn to<T: Unit>(self) -> Period<T> {
let quantity = self.quantity * U::factor::<T>();
Period::new(quantity)
}
}
impl<U> Div<Period<U>> for f64
where
U: Unit,
{
type Output = Frequency<U>;
fn div(self, other: Period<U>) -> Self::Output {
Self::Output::new(self / other.quantity)
}
}
impl<L, T> Div<Period<T>> for Length<L>
where
L: length::Unit,
T: Unit,
{
type Output = Speed<L, T>;
fn div(self, per: Period<T>) -> Self::Output {
Speed::new(self.quantity / per.quantity)
}
}
impl<U> Frequency<U>
where
U: Unit,
{
pub fn new(quantity: f64) -> Self {
Frequency::<U> {
quantity,
unit: PhantomData,
}
}
pub fn to<T: Unit>(self) -> Frequency<T> {
let quantity = self.quantity / U::factor::<T>();
Frequency::new(quantity)
}
}
impl<U> Div<Frequency<U>> for f64
where
U: Unit,
{
type Output = Period<U>;
fn div(self, other: Frequency<U>) -> Self::Output {
Self::Output::new(self / other.quantity)
}
}
impl<L, T> Mul<Length<L>> for Frequency<T>
where
L: length::Unit,
T: Unit,
{
type Output = Speed<L, T>;
fn mul(self, len: Length<L>) -> Self::Output {
Speed::new(self.quantity * len.quantity)
}
}
impl<L, T> Mul<Frequency<T>> for Length<L>
where
L: length::Unit,
T: Unit,
{
type Output = Speed<L, T>;
fn mul(self, freq: Frequency<T>) -> Self::Output {
Speed::new(self.quantity * freq.quantity)
}
}