Skip to content

Commit c7d3677

Browse files
author
Jonathan Pallant
committed
Add Power.
1 parent 1425a10 commit c7d3677

File tree

6 files changed

+239
-2
lines changed

6 files changed

+239
-2
lines changed

examples/format_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use measurements::Weight;
77
use measurements::Speed;
88
use measurements::Acceleration;
99
use measurements::Energy;
10+
use measurements::Power;
1011

1112
fn main() {
1213
for power in -12..12 {
@@ -20,7 +21,6 @@ fn main() {
2021
println!("Speed of {0:.3}", Speed::from_meters_per_second(val));
2122
println!("Acceleration of {0:.3}", Acceleration::from_meters_per_second_per_second(val));
2223
println!("Energy of {0:.3}", Energy::from_joules(val));
24+
println!("Power of {0:.3}", Power::from_watts(val));
2325
}
24-
25-
println!("1.0 GeV is {}", Energy::from_e_v(1e9));
2626
}

src/energy.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use super::measurement::*;
2+
use super::Power;
3+
use std::time::Duration;
24

35
/// The `Energy` struct can be used to deal with energies in a common way.
46
/// Common metric and imperial units are supported.
@@ -66,6 +68,28 @@ impl Energy {
6668
}
6769
}
6870

71+
/// Energy / Time = Power
72+
impl ::std::ops::Div<Duration> for Energy {
73+
type Output = Power;
74+
75+
fn div(self, rhs: Duration) -> Power {
76+
// It would be useful if Duration had a method that did this...
77+
let seconds: f64 = rhs.as_secs() as f64 + ((rhs.subsec_nanos() as f64) * 1e-9);
78+
Power::from_watts(self.as_joules() / seconds)
79+
}
80+
}
81+
82+
/// Energy / Power = Time
83+
impl ::std::ops::Div<Power> for Energy {
84+
type Output = Duration;
85+
86+
fn div(self, rhs: Power) -> Duration {
87+
let seconds = self.as_joules() / rhs.as_watts();
88+
let nanosecs = (seconds * 1e9) % 1e9;
89+
Duration::new(seconds as u64, nanosecs as u32)
90+
}
91+
}
92+
6993
impl Measurement for Energy {
7094
fn get_base_units(&self) -> f64 {
7195
self.joules

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ pub use acceleration::Acceleration;
2626
pub mod energy;
2727
pub use energy::Energy;
2828

29+
pub mod power;
30+
pub use power::Power;
31+
2932
// Include when running tests, but don't export them
3033
#[cfg(test)]
3134
#[allow(dead_code)]

src/power.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
use super::measurement::*;
2+
use std::time::Duration;
3+
use super::Energy;
4+
5+
/// The `Power` struct can be used to deal with energies in a common way.
6+
/// Common metric and imperial units are supported.
7+
///
8+
/// # Example
9+
///
10+
/// ```
11+
/// use measurements::Power;
12+
///
13+
/// let power = Power::from_horsepower(100.0);
14+
/// let k_w = power.as_kilowatts();
15+
/// println!("A 100.0 hp car produces {} kW", k_w);
16+
/// ```
17+
#[derive(Copy, Clone, Debug)]
18+
pub struct Power {
19+
watts: f64,
20+
}
21+
22+
impl Power {
23+
pub fn from_watts(watts: f64) -> Power {
24+
Power { watts: watts }
25+
}
26+
27+
pub fn from_horsepower(horsepower: f64) -> Power {
28+
Self::from_watts(horsepower * 745.6998715822702)
29+
}
30+
31+
pub fn from_btu_per_minute(btu_per_minute: f64) -> Power {
32+
Self::from_watts(btu_per_minute * 17.58426666666667)
33+
}
34+
35+
pub fn from_kilowatts(kw: f64) -> Power {
36+
Self::from_watts(kw * 1000.0)
37+
}
38+
39+
pub fn as_watts(&self) -> f64 {
40+
self.watts
41+
}
42+
43+
pub fn as_horsepower(&self) -> f64 {
44+
self.watts / 745.6998715822702
45+
}
46+
47+
pub fn as_btu_per_minute(&self) -> f64 {
48+
self.watts / 17.58426666666667
49+
}
50+
51+
pub fn as_kilowatts(&self) -> f64 {
52+
self.watts / 1000.0
53+
}
54+
}
55+
56+
/// Power * Time = Energy
57+
impl ::std::ops::Mul<Duration> for Power {
58+
type Output = Energy;
59+
60+
fn mul(self, rhs: Duration) -> Energy {
61+
// It would be useful if Duration had a method that did this...
62+
let seconds: f64 = rhs.as_secs() as f64 + ((rhs.subsec_nanos() as f64) * 1e-9);
63+
Energy::from_joules(self.as_watts() * seconds)
64+
}
65+
}
66+
67+
/// Time * Power = Energy
68+
impl ::std::ops::Mul<Power> for Duration {
69+
type Output = Energy;
70+
71+
fn mul(self, rhs: Power) -> Energy {
72+
rhs * self
73+
}
74+
}
75+
76+
impl Measurement for Power {
77+
fn get_base_units(&self) -> f64 {
78+
self.watts
79+
}
80+
81+
fn from_base_units(units: f64) -> Self {
82+
Self::from_watts(units)
83+
}
84+
85+
fn get_base_units_name(&self) -> &'static str {
86+
"W"
87+
}
88+
89+
fn get_appropriate_units(&self) -> (&'static str, f64) {
90+
// Smallest to Largest
91+
let list = [
92+
("fW", 1e-15),
93+
("pW", 1e-12),
94+
("nW", 1e-9),
95+
("\u{00B5}W", 1e-6),
96+
("mW", 1e-3),
97+
("W", 1e0),
98+
("kW", 1e3),
99+
("MW", 1e6),
100+
("GW", 1e9),
101+
("TW", 1e12),
102+
("PW", 1e15),
103+
("EW", 1e18),
104+
];
105+
self.pick_appropriate_units(&list)
106+
}
107+
}
108+
109+
implement_measurement! { Power }

src/tests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod volume_tests;
55
mod speed_tests;
66
mod acceleration_tests;
77
mod energy_tests;
8+
mod power_tests;
89

910
const DEFAULT_DELTA: f64 = 0.00001;
1011

src/tests/power_tests.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use power::*;
2+
use super::assert_almost_eq;
3+
4+
#[test]
5+
pub fn as_btu_per_minute() {
6+
let i1 = Power::from_btu_per_minute(100.0);
7+
let r1 = i1.as_watts();
8+
9+
let i2 = Power::from_watts(100.0);
10+
let r2 = i2.as_btu_per_minute();
11+
12+
assert_almost_eq(r1, 1758.426666666667);
13+
assert_almost_eq(r2, 5.686901927480627);
14+
}
15+
16+
#[test]
17+
pub fn as_horsepower() {
18+
let i1 = Power::from_horsepower(100.0);
19+
let r1 = i1.as_watts();
20+
21+
let i2 = Power::from_watts(100.0);
22+
let r2 = i2.as_horsepower();
23+
24+
assert_almost_eq(r1, 74569.98715822702);
25+
assert_almost_eq(r2, 0.1341022089595028);
26+
}
27+
28+
#[test]
29+
pub fn as_kilowatts() {
30+
let i1 = Power::from_kilowatts(100.0);
31+
let r1 = i1.as_watts();
32+
33+
let i2 = Power::from_watts(100.0);
34+
let r2 = i2.as_kilowatts();
35+
36+
assert_almost_eq(r1, 100000.0);
37+
assert_almost_eq(r2, 0.1);
38+
}
39+
40+
// Traits
41+
#[test]
42+
fn add() {
43+
let a = Power::from_watts(2.0);
44+
let b = Power::from_watts(4.0);
45+
let c = a + b;
46+
let d = b + a;
47+
assert_almost_eq(c.as_watts(), 6.0);
48+
assert_eq!(c, d);
49+
}
50+
51+
#[test]
52+
fn sub() {
53+
let a = Power::from_watts(2.0);
54+
let b = Power::from_watts(4.0);
55+
let c = a - b;
56+
assert_almost_eq(c.as_watts(), -2.0);
57+
}
58+
59+
#[test]
60+
fn mul() {
61+
let a = Power::from_watts(3.0);
62+
let b = a * 2.0;
63+
let c = 2.0 * a;
64+
assert_almost_eq(b.as_watts(), 6.0);
65+
assert_eq!(b, c);
66+
}
67+
68+
#[test]
69+
fn div() {
70+
let a = Power::from_watts(2.0);
71+
let b = Power::from_watts(4.0);
72+
let c = a / b;
73+
let d = a / 2.0;
74+
assert_almost_eq(c, 0.5);
75+
assert_almost_eq(d.as_watts(), 1.0);
76+
}
77+
78+
#[test]
79+
fn eq() {
80+
let a = Power::from_watts(2.0);
81+
let b = Power::from_watts(2.0);
82+
assert_eq!(a == b, true);
83+
}
84+
85+
#[test]
86+
fn neq() {
87+
let a = Power::from_watts(2.0);
88+
let b = Power::from_watts(4.0);
89+
assert_eq!(a == b, false);
90+
}
91+
92+
#[test]
93+
fn cmp() {
94+
let a = Power::from_watts(2.0);
95+
let b = Power::from_watts(4.0);
96+
assert_eq!(a < b, true);
97+
assert_eq!(a <= b, true);
98+
assert_eq!(a > b, false);
99+
assert_eq!(a >= b, false);
100+
}

0 commit comments

Comments
 (0)