use core::fmt::Display;
use crate::float::Float;
use crate::{Angle, AngleUnbounded};
macro_rules! unit {
(
$Unit:ident, $doc:expr, $to_method:ident, $from_method:ident, $format:expr
) => {
#[doc = $doc]
#[derive(Debug, Copy, Clone)]
#[repr(transparent)]
pub struct $Unit<A>(pub A);
impl<F: Float> $Unit<Angle<F>> {
#[doc = $doc]
#[inline]
pub fn to_value(self) -> F {
self.0.$to_method()
}
#[doc = $doc]
#[inline]
pub fn from_value(x: F) -> Self {
Self(Angle::$from_method(x))
}
}
impl<F: Float> $Unit<AngleUnbounded<F>> {
#[doc = $doc]
#[inline]
pub fn to_value(self) -> F {
self.0.$to_method()
}
#[doc = $doc]
#[inline]
pub fn from_value(x: F) -> Self {
Self(AngleUnbounded::$from_method(x))
}
}
impl<A> From<A> for $Unit<A> {
#[inline]
fn from(x: A) -> Self {
Self(x)
}
}
impl<F: Float + Display> Display for $Unit<Angle<F>> {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, $format, self.to_value())
}
}
impl<F: Float + Display> Display for $Unit<AngleUnbounded<F>> {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, $format, self.to_value())
}
}
};
}
unit!(Radians, "radian", to_radians, from_radians, "{} rad");
unit!(Degrees, "degree", to_degrees, from_degrees, "{}°");
unit!(Turns, "turn", to_turns, from_turns, "{} tr");
unit!(Gradians, "gradian", to_gradians, from_gradians, "{}g");