use core::fmt;
use core::ops::{Add, Div, Mul, Neg, Sub};
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct Temperature(pub f64);
impl Temperature {
pub fn from_celsius(c: f64) -> Self {
Self(c + 273.15)
}
pub fn to_celsius(self) -> f64 {
self.0 - 273.15
}
pub fn from_kelvin(k: f64) -> Self {
Self(k)
}
}
impl fmt::Display for Temperature {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:.2} K ({:.2} \u{00b0}C)", self.0, self.to_celsius())
}
}
impl Add for Temperature {
type Output = Self;
fn add(self, rhs: Self) -> Self {
Self(self.0 + rhs.0)
}
}
impl Sub for Temperature {
type Output = Self;
fn sub(self, rhs: Self) -> Self {
Self(self.0 - rhs.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct ThermalConductivity(pub f64);
impl fmt::Display for ThermalConductivity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:.4} W/(m\u{00b7}K)", self.0)
}
}
impl Mul<f64> for ThermalConductivity {
type Output = Self;
fn mul(self, rhs: f64) -> Self {
Self(self.0 * rhs)
}
}
impl Div<f64> for ThermalConductivity {
type Output = Self;
fn div(self, rhs: f64) -> Self {
Self(self.0 / rhs)
}
}
impl Neg for ThermalConductivity {
type Output = Self;
fn neg(self) -> Self {
Self(-self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
pub struct HeatCapacity(pub f64);
impl fmt::Display for HeatCapacity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:.4} J/(kg\u{00b7}K)", self.0)
}
}
impl Mul<f64> for HeatCapacity {
type Output = Self;
fn mul(self, rhs: f64) -> Self {
Self(self.0 * rhs)
}
}
impl Div<f64> for HeatCapacity {
type Output = Self;
fn div(self, rhs: f64) -> Self {
Self(self.0 / rhs)
}
}
impl Neg for HeatCapacity {
type Output = Self;
fn neg(self) -> Self {
Self(-self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_temperature_conversion() {
let t = Temperature::from_celsius(25.0);
assert!((t.0 - 298.15).abs() < 1e-10);
assert!((t.to_celsius() - 25.0).abs() < 1e-10);
}
#[test]
fn test_temperature_display() {
let t = Temperature::from_celsius(25.0);
let s = format!("{t}");
assert!(s.contains("298.15 K"));
assert!(s.contains("25.00"));
}
}