Skip to content

Commit 61313ae

Browse files
authored
Merge pull request #15 from dbrgn/ohms-law
Add Current and Resistance units
2 parents 84c14b8 + 6113f4b commit 61313ae

File tree

5 files changed

+401
-0
lines changed

5 files changed

+401
-0
lines changed

src/current.rs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
//! Types and constants for handling electrical current.
2+
3+
use super::measurement::*;
4+
5+
/// The `Current` struct can be used to deal with electric potential difference
6+
/// in a common way.
7+
///
8+
/// # Example
9+
///
10+
/// ```
11+
/// use measurements::Current;
12+
///
13+
/// let amperes = Current::from_milliamperes(35.0);
14+
/// let a = amperes.as_amperes();
15+
/// let u_a = amperes.as_microamperes();
16+
/// println!("35 mA correspond to {} A or {} µA", a, u_a);
17+
/// ```
18+
#[derive(Copy, Clone, Debug)]
19+
pub struct Current {
20+
amperes: f64,
21+
}
22+
23+
impl Current {
24+
/// Create a new Current from a floating point value in amperes
25+
pub fn from_amperes(amperes: f64) -> Self {
26+
Current { amperes }
27+
}
28+
29+
/// Create a new Current from a floating point value in milliamperes
30+
pub fn from_milliamperes(milliamperes: f64) -> Self {
31+
Self::from_amperes(milliamperes / 1000.0)
32+
}
33+
34+
/// Create a new Current from a floating point value in microamperes
35+
pub fn from_microamperes(microamperes: f64) -> Self {
36+
Self::from_amperes(microamperes / 1000.0 / 1000.0)
37+
}
38+
39+
/// Convert this Current into a floating point value in amperes
40+
pub fn as_amperes(&self) -> f64 {
41+
self.amperes
42+
}
43+
44+
/// Convert this Current into a floating point value in milliamperes
45+
pub fn as_milliamperes(&self) -> f64 {
46+
self.amperes * 1000.0
47+
}
48+
49+
/// Convert this Current into a floating point value in microamperes
50+
pub fn as_microamperes(&self) -> f64 {
51+
self.amperes * 1000.0 * 1000.0
52+
}
53+
}
54+
55+
impl Measurement for Current {
56+
fn as_base_units(&self) -> f64 {
57+
self.amperes
58+
}
59+
60+
fn from_base_units(units: f64) -> Self {
61+
Self::from_amperes(units)
62+
}
63+
64+
fn get_base_units_name(&self) -> &'static str {
65+
"A"
66+
}
67+
68+
fn get_appropriate_units(&self) -> (&'static str, f64) {
69+
// Smallest to Largest
70+
let list = [
71+
("fA", 1e-15),
72+
("pA", 1e-12),
73+
("nA", 1e-9),
74+
("\u{00B5}A", 1e-6),
75+
("mA", 1e-3),
76+
("A", 1e0),
77+
("kA", 1e3),
78+
("MA", 1e6),
79+
("GA", 1e9),
80+
("TA", 1e12),
81+
("PA", 1e15),
82+
("EA", 1e18),
83+
];
84+
self.pick_appropriate_units(&list)
85+
}
86+
}
87+
88+
implement_measurement! { Current }
89+
90+
#[cfg(test)]
91+
mod test {
92+
use current::*;
93+
use test_utils::assert_almost_eq;
94+
95+
#[test]
96+
pub fn as_amperes() {
97+
let u = Current::from_milliamperes(1234.0);
98+
assert_almost_eq(u.as_amperes(), 1.234);
99+
}
100+
101+
#[test]
102+
pub fn as_milliamperes() {
103+
let u = Current::from_amperes(1.234);
104+
assert_almost_eq(u.as_milliamperes(), 1234.0);
105+
}
106+
107+
#[test]
108+
pub fn as_microamperes() {
109+
let u = Current::from_amperes(0.001);
110+
assert_almost_eq(u.as_microamperes(), 1000.0);
111+
}
112+
113+
// Traits
114+
#[test]
115+
fn add() {
116+
let a = Current::from_amperes(2.0);
117+
let b = Current::from_milliamperes(4000.0);
118+
let c = a + b;
119+
assert_almost_eq(c.as_amperes(), 6.0);
120+
}
121+
122+
#[test]
123+
fn sub() {
124+
let a = Current::from_amperes(2.0);
125+
let b = Current::from_milliamperes(4000.0);
126+
let c = a - b;
127+
assert_almost_eq(c.as_amperes(), -2.0);
128+
}
129+
130+
#[test]
131+
fn mul() {
132+
let a = Current::from_milliamperes(2000.0);
133+
let b = 4.0 * a;
134+
assert_almost_eq(b.as_amperes(), 8.0);
135+
}
136+
137+
#[test]
138+
fn div() {
139+
let a = Current::from_amperes(2.0);
140+
let b = Current::from_milliamperes(4000.0);
141+
let c = a / b;
142+
let d = a / 2.0;
143+
assert_almost_eq(c, 0.5);
144+
assert_almost_eq(d.as_amperes(), 1.0);
145+
}
146+
147+
#[test]
148+
fn eq() {
149+
let a = Current::from_microamperes(1_000_000.0);
150+
let b = Current::from_milliamperes(1_000.0);
151+
assert_eq!(a, b);
152+
}
153+
154+
#[test]
155+
fn neq() {
156+
let a = Current::from_amperes(2.0);
157+
let b = Current::from_milliamperes(2.0);
158+
assert_ne!(a, b);
159+
}
160+
161+
#[test]
162+
fn cmp() {
163+
let a = Current::from_amperes(2.0);
164+
let b = Current::from_amperes(4.0);
165+
assert_eq!(a < b, true);
166+
assert_eq!(a <= b, true);
167+
assert_eq!(a > b, false);
168+
assert_eq!(a >= b, false);
169+
}
170+
171+
}

src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ pub use power::Power;
4545
pub mod voltage;
4646
pub use voltage::Voltage;
4747

48+
pub mod current;
49+
pub use current::Current;
50+
51+
pub mod resistance;
52+
pub use resistance::Resistance;
53+
4854
pub mod force;
4955
pub use force::Force;
5056

@@ -154,6 +160,8 @@ impl_maths!(Power, Force, Speed);
154160
impl_maths!(Speed, time::Duration, Acceleration);
155161
impl_maths!(Volume, Length, Area);
156162
impl_maths!(Power, AngularVelocity, Torque);
163+
impl_maths!(Power, Voltage, Current);
164+
impl_maths!(Voltage, Resistance, Current);
157165

158166
// Force * Distance is ambiguous. Create an ambiguous struct the user can then
159167
// cast into either Torque or Energy.

src/power.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ implement_measurement! { Power }
128128
#[cfg(test)]
129129
mod test {
130130
use power::*;
131+
use current::*;
132+
use voltage::*;
131133
use test_utils::assert_almost_eq;
132134

133135
#[test]
@@ -228,4 +230,28 @@ mod test {
228230
assert_eq!(a >= b, false);
229231
}
230232

233+
#[test]
234+
fn mul_voltage_current() {
235+
let u = Voltage::from_volts(230.0);
236+
let i = Current::from_amperes(10.0);
237+
let p = u * i;
238+
assert_almost_eq(p.as_kilowatts(), 2.3);
239+
}
240+
241+
#[test]
242+
fn div_voltage() {
243+
let u = Voltage::from_volts(230.0);
244+
let p = Power::from_kilowatts(2.3);
245+
let i = p / u;
246+
assert_eq!(i.as_amperes(), 10.0);
247+
}
248+
249+
#[test]
250+
fn div_current() {
251+
let i = Current::from_amperes(10.0);
252+
let p = Power::from_kilowatts(2.3);
253+
let u = p / i;
254+
assert_eq!(u.as_volts(), 230.0);
255+
}
256+
231257
}

0 commit comments

Comments
 (0)