#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(any(feature = "checked", doc))]
pub mod checked;
#[cfg(all(any(feature = "checked", doc), std))]
pub use self::checked::CheckedTemperature;
#[cfg(not(feature = "f32"))]
type Float = f64;
#[cfg(feature = "f32")]
type Float = f32;
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(all(feature = "arbitrary", std), derive(arbitrary::Arbitrary))]
pub enum Temperature {
Fahrenheit(self::Float),
Celsius(self::Float),
Kelvin(self::Float),
}
impl Temperature {
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
pub fn to_fahrenheit(&self) -> Temperature {
match self {
Self::Fahrenheit(_) => *self,
Self::Celsius(c) => Self::Fahrenheit((c * 1.8) + 32.0),
Self::Kelvin(k) => Self::Fahrenheit(((k - 273.15) * 1.8) + 32.0),
}
}
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
pub fn to_celsius(&self) -> Temperature {
match self {
Temperature::Fahrenheit(f) => Self::Celsius((f - 32.0) / 1.8),
Temperature::Celsius(_) => *self,
Temperature::Kelvin(k) => Self::Celsius(k - 273.15),
}
}
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
pub fn to_kelvin(&self) -> Temperature {
match self {
Temperature::Fahrenheit(f) => Self::Kelvin(((f - 32.0) / 1.8) + 273.15),
Temperature::Celsius(c) => Self::Kelvin(c + 273.15),
Temperature::Kelvin(_) => *self,
}
}
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
pub fn into_inner(self) -> Float {
Into::<Float>::into(self)
}
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
pub const fn get_inner(&self) -> Float {
match self {
Temperature::Fahrenheit(t) => *t,
Temperature::Celsius(t) => *t,
Temperature::Kelvin(t) => *t,
}
}
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
pub fn is_below_abs_zero(&self) -> bool {
match self {
Temperature::Fahrenheit(f) => *f < -459.67,
Temperature::Celsius(c) => *c < -273.15,
Temperature::Kelvin(k) => *k < 0.0,
}
}
#[cfg_attr(feature = "f32", doc = "```ignore")]
#[cfg_attr(not(feature = "f32"), doc = "```")]
pub fn is_nan(&self) -> bool {
match self {
Temperature::Celsius(t) | Temperature::Fahrenheit(t) | Temperature::Kelvin(t) => {
t.is_nan()
}
}
}
}
#[allow(clippy::from_over_into)]
impl Into<Float> for Temperature {
fn into(self) -> Float {
match self {
Temperature::Fahrenheit(f) => f,
Temperature::Celsius(c) => c,
Temperature::Kelvin(k) => k,
}
}
}
impl core::fmt::Display for Temperature {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.get_inner())
}
}
impl ufmt::uDebug for Temperature {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt_write::uWrite + ?Sized,
{
let unit = match self {
Temperature::Fahrenheit(_) => "Fahrenheit",
Temperature::Celsius(_) => "Celsius",
Temperature::Kelvin(_) => "Kelvin",
};
#[cfg(feature = "f32")]
return ufmt::uwrite!(
f,
"Temperature::{}({})",
unit,
ufmt_float::uFmt_f32::Five(self.get_inner())
);
#[cfg(not(feature = "f32"))]
return ufmt::uwrite!(
f,
"Temperature::{}({})",
unit,
ufmt_float::uFmt_f64::Five(self.get_inner())
);
}
}
impl ufmt::uDisplay for Temperature {
fn fmt<W>(&self, f: &mut ufmt::Formatter<'_, W>) -> Result<(), W::Error>
where
W: ufmt_write::uWrite + ?Sized,
{
#[cfg(feature = "f32")]
return ufmt::uwrite!(f, "{}", ufmt_float::uFmt_f32::Five(self.get_inner()));
#[cfg(not(feature = "f32"))]
return ufmt::uwrite!(f, "{}", ufmt_float::uFmt_f64::Five(self.get_inner()));
}
}
impl core::ops::Add for Temperature {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
match self {
Temperature::Fahrenheit(f) => {
Temperature::Fahrenheit(f + rhs.to_fahrenheit().into_inner())
}
Temperature::Celsius(c) => Temperature::Celsius(c + rhs.to_celsius().into_inner()),
Temperature::Kelvin(k) => Temperature::Kelvin(k + rhs.to_kelvin().into_inner()),
}
}
}
impl core::ops::Sub for Temperature {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
match self {
Temperature::Fahrenheit(f) => {
Temperature::Fahrenheit(f - rhs.to_fahrenheit().into_inner())
}
Temperature::Celsius(c) => Temperature::Celsius(c - rhs.to_celsius().into_inner()),
Temperature::Kelvin(k) => Temperature::Kelvin(k - rhs.to_kelvin().into_inner()),
}
}
}
impl core::ops::Div<Float> for Temperature {
type Output = Self;
fn div(self, rhs: Float) -> Self::Output {
match self {
Temperature::Fahrenheit(f) => Temperature::Fahrenheit(f / rhs),
Temperature::Celsius(c) => Temperature::Celsius(c / rhs),
Temperature::Kelvin(k) => Temperature::Kelvin(k / rhs),
}
}
}
impl core::ops::Mul<Float> for Temperature {
type Output = Self;
fn mul(self, rhs: Float) -> Self::Output {
match self {
Temperature::Fahrenheit(f) => Temperature::Fahrenheit(f * rhs),
Temperature::Celsius(c) => Temperature::Celsius(c * rhs),
Temperature::Kelvin(k) => Temperature::Kelvin(k * rhs),
}
}
}