Skip to content

Commit f9e80cd

Browse files
committed
Added TemperatureDelta.
Temperatures can't be added, multiplied or divided like other measurements.
1 parent 16b7bcf commit f9e80cd

File tree

4 files changed

+134
-40
lines changed

4 files changed

+134
-40
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "measurements"
3-
version = "0.3.0"
3+
version = "0.4.0"
44
authors = ["James O'Cull <[email protected]>",
55
"Jonathan Pallant <[email protected]>",
66
"Hannah McLaughlin <[email protected]>"]

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub mod length;
66
pub use length::Length;
77

88
pub mod temperature;
9-
pub use temperature::Temperature;
9+
pub use temperature::{Temperature, TemperatureDelta};
1010

1111
pub mod weight;
1212
pub use weight::Weight;

src/temperature.rs

Lines changed: 123 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,57 +13,163 @@ use super::measurement::*;
1313
/// ```
1414
#[derive(Copy, Clone, Debug)]
1515
pub struct Temperature {
16-
kelvin: f64,
16+
degrees_kelvin: f64,
17+
}
18+
19+
/// The `TemperatureDelta` struct can be used to deal with differences between
20+
/// temperatures in a common way.
21+
///
22+
/// # Example
23+
///
24+
/// ```
25+
/// use measurements::{Temperature, TemperatureDelta};
26+
///
27+
/// let boiling_water = Temperature::from_celsius(100.0);
28+
/// let frozen_water = Temperature::from_celsius(0.0);
29+
/// let difference = boiling_water - frozen_water;
30+
/// println!("Boiling water is {} above freezing.", difference);
31+
/// ```
32+
#[derive(Copy, Clone, Debug)]
33+
pub struct TemperatureDelta {
34+
kelvin_degrees: f64,
35+
}
36+
37+
impl TemperatureDelta {
38+
pub fn from_kelvin(kelvin_degrees: f64) -> Self {
39+
TemperatureDelta { kelvin_degrees: kelvin_degrees }
40+
}
41+
42+
pub fn from_celsius(celsius_degrees: f64) -> Self {
43+
TemperatureDelta::from_kelvin(celsius_degrees)
44+
}
45+
46+
pub fn from_fahrenheit(farenheit_degrees: f64) -> Self {
47+
TemperatureDelta { kelvin_degrees: farenheit_degrees / 1.8}
48+
}
49+
50+
pub fn from_rankine(rankine_degrees: f64) -> Self {
51+
TemperatureDelta { kelvin_degrees: rankine_degrees / 1.8}
52+
}
53+
54+
pub fn as_kelvin(&self) -> f64 {
55+
self.kelvin_degrees
56+
}
57+
58+
pub fn as_celsius(&self) -> f64 {
59+
self.kelvin_degrees
60+
}
61+
62+
pub fn as_fahrenheit(&self) -> f64 {
63+
self.kelvin_degrees * 1.8
64+
}
65+
66+
pub fn as_rankine(&self) -> f64 {
67+
self.kelvin_degrees * 1.8
68+
}
1769
}
1870

1971
impl Temperature {
20-
pub fn from_kelvin(kelvin: f64) -> Self {
21-
Temperature { kelvin: kelvin }
72+
pub fn from_kelvin(degrees_kelvin: f64) -> Self {
73+
Temperature { degrees_kelvin: degrees_kelvin }
2274
}
2375

24-
pub fn from_celsius(celsius: f64) -> Self {
25-
Self::from_kelvin(celsius + 273.15)
76+
pub fn from_celsius(degrees_celsius: f64) -> Self {
77+
Self::from_kelvin(degrees_celsius + 273.15)
2678
}
2779

28-
pub fn from_fahrenheit(fahrenheit: f64) -> Self {
29-
Self::from_kelvin((fahrenheit - 32.0) / 1.8 + 273.15)
80+
pub fn from_fahrenheit(degrees_fahrenheit: f64) -> Self {
81+
Self::from_kelvin((degrees_fahrenheit - 32.0) / 1.8 + 273.15)
3082
}
3183

32-
pub fn from_rankine(rankine: f64) -> Self {
33-
Self::from_kelvin((rankine - 491.67) / 1.8 + 273.15)
84+
pub fn from_rankine(degrees_rankine: f64) -> Self {
85+
Self::from_kelvin((degrees_rankine - 491.67) / 1.8 + 273.15)
3486
}
3587

3688
pub fn as_kelvin(&self) -> f64 {
37-
self.kelvin
89+
self.degrees_kelvin
3890
}
3991

4092
pub fn as_celsius(&self) -> f64 {
41-
self.kelvin - 273.15
93+
self.degrees_kelvin - 273.15
4294
}
4395

4496
pub fn as_fahrenheit(&self) -> f64 {
45-
(self.kelvin - 273.15) * 1.8 + 32.0
97+
(self.degrees_kelvin - 273.15) * 1.8 + 32.0
4698
}
4799

48100
pub fn as_rankine(&self) -> f64 {
49-
(self.kelvin - 273.15) * 1.8 + 491.67
101+
(self.degrees_kelvin - 273.15) * 1.8 + 491.67
50102
}
51103
}
52104

53105
impl Measurement for Temperature {
54106
fn get_base_units(&self) -> f64 {
55-
self.kelvin
107+
self.degrees_kelvin
108+
}
109+
110+
fn from_base_units(degrees_kelvin: f64) -> Self {
111+
Self::from_kelvin(degrees_kelvin)
56112
}
113+
}
114+
115+
impl ::std::ops::Add<TemperatureDelta> for Temperature {
116+
type Output = Temperature;
57117

58-
fn from_base_units(units: f64) -> Self {
59-
Self::from_kelvin(units)
118+
fn add(self, other: TemperatureDelta) -> Temperature {
119+
Temperature::from_kelvin(self.degrees_kelvin + other.kelvin_degrees)
60120
}
61121
}
62122

63-
implement_measurement! { Temperature }
123+
impl ::std::ops::Sub<TemperatureDelta> for Temperature {
124+
type Output = Temperature;
125+
126+
fn sub(self, other: TemperatureDelta) -> Temperature {
127+
Temperature::from_kelvin(self.degrees_kelvin - other.kelvin_degrees)
128+
}
129+
}
130+
131+
impl ::std::ops::Sub<Temperature> for Temperature {
132+
type Output = TemperatureDelta;
133+
134+
fn sub(self, other: Temperature) -> TemperatureDelta {
135+
TemperatureDelta::from_kelvin(self.degrees_kelvin - other.degrees_kelvin)
136+
}
137+
}
138+
139+
impl ::std::cmp::Eq for Temperature { }
140+
impl ::std::cmp::PartialEq for Temperature {
141+
fn eq(&self, other: &Self) -> bool {
142+
self.get_base_units() == other.get_base_units()
143+
}
144+
}
145+
146+
impl ::std::cmp::PartialOrd for Temperature {
147+
fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> {
148+
self.get_base_units().partial_cmp(&other.get_base_units())
149+
}
150+
}
151+
152+
impl ::std::cmp::Eq for TemperatureDelta { }
153+
impl ::std::cmp::PartialEq for TemperatureDelta {
154+
fn eq(&self, other: &Self) -> bool {
155+
self.kelvin_degrees == other.kelvin_degrees
156+
}
157+
}
158+
159+
impl ::std::cmp::PartialOrd for TemperatureDelta {
160+
fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> {
161+
self.kelvin_degrees.partial_cmp(&other.kelvin_degrees)
162+
}
163+
}
64164

65165
impl ::std::fmt::Display for Temperature {
66166
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
67167
write!(f, "{:.1} \u{00B0}C", self.as_celsius())
68168
}
69169
}
170+
171+
impl ::std::fmt::Display for TemperatureDelta {
172+
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
173+
write!(f, "{:.1} C\u{00B0}", self.as_celsius())
174+
}
175+
}

src/tests/temperature_tests.rs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,37 +38,25 @@ fn rankine() {
3838
#[test]
3939
fn add() {
4040
let a = Temperature::from_kelvin(2.0);
41-
let b = Temperature::from_kelvin(4.0);
41+
let b = TemperatureDelta::from_kelvin(4.0);
4242
let c = a + b;
4343
assert_almost_eq(c.as_kelvin(), 6.0);
4444
}
4545

4646
#[test]
4747
fn sub() {
48-
let a = Temperature::from_kelvin(2.0);
49-
let b = Temperature::from_kelvin(4.0);
48+
let a = Temperature::from_kelvin(4.0);
49+
let b = TemperatureDelta::from_kelvin(2.0);
5050
let c = a - b;
51-
assert_almost_eq(c.as_kelvin(), -2.0);
51+
assert_almost_eq(c.as_kelvin(), 2.0);
5252
}
5353

5454
#[test]
55-
fn mul() {
56-
let a = Temperature::from_kelvin(2.0);
57-
let b = Temperature::from_kelvin(4.0);
58-
let c = a * b;
59-
let d = a * 2.0;
60-
assert_almost_eq(c.as_kelvin(), 8.0);
61-
assert_almost_eq(d.as_kelvin(), 4.0);
62-
}
63-
64-
#[test]
65-
fn div() {
66-
let a = Temperature::from_kelvin(2.0);
67-
let b = Temperature::from_kelvin(4.0);
68-
let c = a / b;
69-
let d = a / 2.0;
70-
assert_almost_eq(c, 0.5);
71-
assert_almost_eq(d.as_kelvin(), 1.0);
55+
fn sub2() {
56+
let a = Temperature::from_fahrenheit(212.0);
57+
let b = Temperature::from_celsius(75.0);
58+
let c = a - b;
59+
assert_almost_eq(c.as_kelvin(), 25.0);
7260
}
7361

7462
#[test]

0 commit comments

Comments
 (0)