Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| mod error; | |
| use error::Error; | |
| use std::fmt; | |
| use std::str::FromStr; | |
| pub trait Temperature: Sized { | |
| const ABSOLUTE_ZERO: f64; | |
| const SYMBOL: &'static str; | |
| fn new(value: f64) -> Option<Self>; | |
| fn value(&self) -> f64; | |
| } | |
| macro_rules! temperature { | |
| ($temp:ident $sym:literal $abs_zero:literal) => { | |
| #[derive(Debug)] | |
| pub struct $temp{ value: f64 } | |
| impl Temperature for $temp { | |
| const ABSOLUTE_ZERO: f64 = $abs_zero; | |
| const SYMBOL: &'static str = $sym; | |
| fn new(val: f64) -> Option<Self> { | |
| if val >= Self::ABSOLUTE_ZERO { | |
| Some($temp{ value: val }) | |
| } else { None } | |
| } | |
| fn value(&self) -> f64 { self.value } | |
| } | |
| impl FromStr for $temp { | |
| type Err = Error; | |
| fn from_str(s: &str) -> Result<Self, Self::Err> { | |
| $temp::new(s.parse()?).ok_or(Error::BelowAbsoluteZero) | |
| } | |
| } | |
| impl fmt::Display for $temp { | |
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
| write!(f, "{}{}", self.value, Self::SYMBOL) | |
| } | |
| } | |
| } | |
| } | |
| macro_rules! impl_from_temp { | |
| ($from:ident $to:ident $f:expr) => { | |
| impl From<$from> for $to { | |
| fn from(from: $from) -> Self { | |
| $to::new($f(from.value)).unwrap() | |
| } | |
| } | |
| } | |
| } | |
| temperature!(Celsius "°C" -273.15); | |
| temperature!(Fahrenheit "°F" -459.67); | |
| temperature!(Kelvin "K" 0.0); | |
| temperature!(Rankine "°R" 0.0); | |
| impl_from_temp!(Fahrenheit Celsius |x| (x - 32.0) * 5.0 / 9.0); | |
| impl_from_temp!(Kelvin Celsius |x| x - 273.15); | |
| impl_from_temp!(Rankine Celsius |x| x - 491.67 * 5.0 / 9.0); | |
| impl_from_temp!(Celsius Fahrenheit |x| x * 9.0 / 5.0 + 32.0); | |
| impl_from_temp!(Kelvin Fahrenheit |x| (x - 273.15) * 9.0 / 5.0 + 32.0); | |
| impl_from_temp!(Rankine Fahrenheit |x| x - 459.67); | |
| impl_from_temp!(Celsius Kelvin |x| x + 273.15); | |
| impl_from_temp!(Fahrenheit Kelvin |x| (x - 32.0) * 5.0 / 9.0 + 273.15); | |
| impl_from_temp!(Rankine Kelvin |x| x * 5.0 / 9.0); | |
| impl_from_temp!(Celsius Rankine |x| x * 9.0 / 5.0 + 491.67); | |
| impl_from_temp!(Fahrenheit Rankine |x| x + 459.67); | |
| impl_from_temp!(Kelvin Rankine |x| x * 1.803); |