@@ -13,57 +13,163 @@ use super::measurement::*;
13
13
/// ```
14
14
#[ derive( Copy , Clone , Debug ) ]
15
15
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
+ }
17
69
}
18
70
19
71
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 }
22
74
}
23
75
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 )
26
78
}
27
79
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 )
30
82
}
31
83
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 )
34
86
}
35
87
36
88
pub fn as_kelvin ( & self ) -> f64 {
37
- self . kelvin
89
+ self . degrees_kelvin
38
90
}
39
91
40
92
pub fn as_celsius ( & self ) -> f64 {
41
- self . kelvin - 273.15
93
+ self . degrees_kelvin - 273.15
42
94
}
43
95
44
96
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
46
98
}
47
99
48
100
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
50
102
}
51
103
}
52
104
53
105
impl Measurement for Temperature {
54
106
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)
56
112
}
113
+ }
114
+
115
+ impl :: std:: ops:: Add < TemperatureDelta > for Temperature {
116
+ type Output = Temperature ;
57
117
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 )
60
120
}
61
121
}
62
122
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
+ }
64
164
65
165
impl :: std:: fmt:: Display for Temperature {
66
166
fn fmt ( & self , f : & mut :: std:: fmt:: Formatter ) -> :: std:: fmt:: Result {
67
167
write ! ( f, "{:.1} \u{00B0} C" , self . as_celsius( ) )
68
168
}
69
169
}
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
+ }
0 commit comments