Skip to content

Commit 1425a10

Browse files
author
Jonathan Pallant
committed
Add Energy.
1 parent c8ee7d5 commit 1425a10

File tree

5 files changed

+237
-2
lines changed

5 files changed

+237
-2
lines changed

examples/format_test.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ use measurements::Volume;
66
use measurements::Weight;
77
use measurements::Speed;
88
use measurements::Acceleration;
9+
use measurements::Energy;
910

1011
fn main() {
11-
for power in -9..9 {
12-
let val: f64 = 123.456 * (10.0f64.powf(power as f64));
12+
for power in -12..12 {
13+
let val: f64 = 123.456 * (10f64.powf(power as f64));
1314
println!("10^{}...", power);
1415
println!("Temp of {0:.3} outside", Temperature::from_kelvin(val));
1516
println!("Distance of {0:.3}", Length::from_meters(val));
@@ -18,5 +19,8 @@ fn main() {
1819
println!("Weight of {0:.3}", Weight::from_kilograms(val));
1920
println!("Speed of {0:.3}", Speed::from_meters_per_second(val));
2021
println!("Acceleration of {0:.3}", Acceleration::from_meters_per_second_per_second(val));
22+
println!("Energy of {0:.3}", Energy::from_joules(val));
2123
}
24+
25+
println!("1.0 GeV is {}", Energy::from_e_v(1e9));
2226
}

src/energy.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use super::measurement::*;
2+
3+
/// The `Energy` struct can be used to deal with energies in a common way.
4+
/// Common metric and imperial units are supported.
5+
///
6+
/// # Example
7+
///
8+
/// ```
9+
/// use measurements::Energy;
10+
///
11+
/// let energy = Energy::from_kcalories(2500.0);
12+
/// println!("Some say a health adult male should consume {} per day", energy);
13+
/// ```
14+
#[derive(Copy, Clone, Debug)]
15+
pub struct Energy {
16+
joules: f64,
17+
}
18+
19+
impl Energy {
20+
pub fn from_joules(joules: f64) -> Energy {
21+
Energy { joules: joules }
22+
}
23+
24+
pub fn from_kcalories(kcalories: f64) -> Energy {
25+
Self::from_joules(kcalories * 4186.8)
26+
}
27+
28+
pub fn from_btu(btu: f64) -> Energy {
29+
Self::from_joules(btu * 1055.056)
30+
}
31+
32+
pub fn from_e_v(e_v: f64) -> Energy {
33+
Self::from_joules(e_v / 6.241509479607718e+18)
34+
}
35+
36+
pub fn from_watt_hours(wh: f64) -> Energy {
37+
Self::from_joules(wh * 3600.0)
38+
}
39+
40+
pub fn from_kilowatt_hours(kwh: f64) -> Energy {
41+
Self::from_joules(kwh * 3600.0 * 1000.0)
42+
}
43+
44+
pub fn as_joules(&self) -> f64 {
45+
self.joules
46+
}
47+
48+
pub fn as_kcalories(&self) -> f64 {
49+
self.joules / 4186.8
50+
}
51+
52+
pub fn as_btu(&self) -> f64 {
53+
self.joules / 1055.056
54+
}
55+
56+
pub fn as_e_v(&self) -> f64 {
57+
self.joules * 6.241509479607718e+18
58+
}
59+
60+
pub fn as_watt_hours(&self) -> f64 {
61+
self.joules / 3600.0
62+
}
63+
64+
pub fn as_kilowatt_hours(&self) -> f64 {
65+
self.joules / (3600.0 * 1000.0)
66+
}
67+
}
68+
69+
impl Measurement for Energy {
70+
fn get_base_units(&self) -> f64 {
71+
self.joules
72+
}
73+
74+
fn from_base_units(units: f64) -> Self {
75+
Self::from_joules(units)
76+
}
77+
78+
fn get_base_units_name(&self) -> &'static str {
79+
"J"
80+
}
81+
82+
fn get_appropriate_units(&self) -> (&'static str, f64) {
83+
// Smallest to Largest
84+
let list = [
85+
("fJ", 1e-15),
86+
("pJ", 1e-12),
87+
("nJ", 1e-9),
88+
("\u{00B5}J", 1e-6),
89+
("mJ", 1e-3),
90+
("J", 1e0),
91+
("kJ", 1e3),
92+
("MJ", 1e6),
93+
("GJ", 1e9),
94+
("TJ", 1e12),
95+
("PJ", 1e15),
96+
("EJ", 1e18),
97+
];
98+
self.pick_appropriate_units(&list)
99+
}
100+
}
101+
102+
implement_measurement! { Energy }

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ pub use speed::Speed;
2323
pub mod acceleration;
2424
pub use acceleration::Acceleration;
2525

26+
pub mod energy;
27+
pub use energy::Energy;
28+
2629
// Include when running tests, but don't export them
2730
#[cfg(test)]
2831
#[allow(dead_code)]

src/tests/energy_tests.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use energy::*;
2+
use super::assert_almost_eq;
3+
4+
5+
#[test]
6+
pub fn as_kcalories() {
7+
let i1 = Energy::from_kcalories(100.0);
8+
let r1 = i1.as_joules();
9+
10+
let i2 = Energy::from_joules(100.0);
11+
let r2 = i2.as_kcalories();
12+
13+
assert_almost_eq(r1, 418680.0);
14+
assert_almost_eq(r2, 0.0238845896627496);
15+
}
16+
17+
#[test]
18+
pub fn as_btu() {
19+
let i1 = Energy::from_btu(100.0);
20+
let r1 = i1.as_joules();
21+
22+
let i2 = Energy::from_joules(100.0);
23+
let r2 = i2.as_btu();
24+
25+
assert_almost_eq(r1, 105505.6);
26+
assert_almost_eq(r2, 0.0947816987913438);
27+
}
28+
29+
#[test]
30+
pub fn as_e_v() {
31+
let i1 = Energy::from_e_v(100.0);
32+
let r1 = i1.as_joules();
33+
34+
let i2 = Energy::from_joules(100.0);
35+
let r2 = i2.as_e_v();
36+
37+
assert_almost_eq(r1, 1.60217653e-17);
38+
assert_almost_eq(r2, 6.241509479607718e+20);
39+
}
40+
41+
#[test]
42+
pub fn as_watt_hours() {
43+
let i1 = Energy::from_watt_hours(100.0);
44+
let r1 = i1.as_joules();
45+
46+
let i2 = Energy::from_joules(100.0);
47+
let r2 = i2.as_watt_hours();
48+
49+
assert_almost_eq(r1, 360000.0);
50+
assert_almost_eq(r2, 0.02777777777777777777777777777778);
51+
}
52+
53+
#[test]
54+
pub fn as_kilowatt_hours() {
55+
let i1 = Energy::from_kilowatt_hours(100.0);
56+
let r1 = i1.as_joules();
57+
58+
let i2 = Energy::from_joules(100.0);
59+
let r2 = i2.as_kilowatt_hours();
60+
61+
assert_almost_eq(r1, 360000000.0);
62+
assert_almost_eq(r2, 2.777777777777777777777777777778e-5);
63+
}
64+
65+
// Traits
66+
#[test]
67+
fn add() {
68+
let a = Energy::from_joules(2.0);
69+
let b = Energy::from_joules(4.0);
70+
let c = a + b;
71+
let d = b + a;
72+
assert_almost_eq(c.as_joules(), 6.0);
73+
assert_eq!(c, d);
74+
}
75+
76+
#[test]
77+
fn sub() {
78+
let a = Energy::from_joules(2.0);
79+
let b = Energy::from_joules(4.0);
80+
let c = a - b;
81+
assert_almost_eq(c.as_joules(), -2.0);
82+
}
83+
84+
#[test]
85+
fn mul() {
86+
let a = Energy::from_joules(3.0);
87+
let b = a * 2.0;
88+
let c = 2.0 * a;
89+
assert_almost_eq(b.as_joules(), 6.0);
90+
assert_eq!(b, c);
91+
}
92+
93+
#[test]
94+
fn div() {
95+
let a = Energy::from_joules(2.0);
96+
let b = Energy::from_joules(4.0);
97+
let c = a / b;
98+
let d = a / 2.0;
99+
assert_almost_eq(c, 0.5);
100+
assert_almost_eq(d.as_joules(), 1.0);
101+
}
102+
103+
#[test]
104+
fn eq() {
105+
let a = Energy::from_joules(2.0);
106+
let b = Energy::from_joules(2.0);
107+
assert_eq!(a == b, true);
108+
}
109+
110+
#[test]
111+
fn neq() {
112+
let a = Energy::from_joules(2.0);
113+
let b = Energy::from_joules(4.0);
114+
assert_eq!(a == b, false);
115+
}
116+
117+
#[test]
118+
fn cmp() {
119+
let a = Energy::from_joules(2.0);
120+
let b = Energy::from_joules(4.0);
121+
assert_eq!(a < b, true);
122+
assert_eq!(a <= b, true);
123+
assert_eq!(a > b, false);
124+
assert_eq!(a >= b, false);
125+
}

src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod weight_tests;
44
mod volume_tests;
55
mod speed_tests;
66
mod acceleration_tests;
7+
mod energy_tests;
78

89
const DEFAULT_DELTA: f64 = 0.00001;
910

0 commit comments

Comments
 (0)