frequenz_microgrid/quantity/
current.rs

1// License: MIT
2// Copyright © 2025 Frequenz Energy-as-a-Service GmbH
3
4//! This module defines the `Current` quantity and its operations.
5
6use super::{Power, Voltage};
7
8qty_ctor! {
9    #[doc = "A physical quantity representing electric current."]
10    Current => {
11        (from_milliamperes, as_milliamperes, "mA", 1e-3),
12        (from_amperes, as_amperes, "A", 1e0),
13    }
14}
15
16impl std::ops::Mul<Voltage> for Current {
17    type Output = Power;
18
19    fn mul(self, voltage: Voltage) -> Self::Output {
20        Power::from_watts(self.as_amperes() * voltage.as_volts())
21    }
22}
23
24#[cfg(test)]
25mod tests {
26    use crate::quantity::{Percentage, Quantity as _, Voltage, test_utils::assert_f32_eq};
27
28    use super::Current;
29
30    #[test]
31    fn test_current() {
32        let current_1 = Current::from_milliamperes(1000.0);
33        let current_2 = Current::from_amperes(1.2);
34        assert_f32_eq(current_1.as_amperes(), 1.0);
35        assert_f32_eq(current_2.as_milliamperes(), 1200.0);
36
37        assert!(current_1 < current_2);
38        assert!(current_2 > current_1);
39
40        assert_f32_eq((current_1 + current_2).as_amperes(), 2.2);
41        assert_f32_eq((current_2 - current_1).as_amperes(), 0.2);
42        assert_f32_eq((current_2 * 2.0).as_amperes(), 2.4);
43        assert_f32_eq(
44            (current_2 * Percentage::from_percentage(50.0)).as_amperes(),
45            0.6,
46        );
47        assert_f32_eq((current_2 / 3.0).as_amperes(), 0.4);
48        assert_f32_eq(current_2 / current_1, 1.2);
49
50        assert_f32_eq(Current::zero().as_amperes(), 0.0);
51    }
52
53    #[test]
54    fn test_current_power_voltage() {
55        let current = Current::from_amperes(2.0);
56        let voltage = Voltage::from_volts(230.0);
57        let power = current * voltage;
58        assert_f32_eq(power.as_watts(), 460.0);
59    }
60
61    #[test]
62    fn test_current_formatting() {
63        let s = |value| Current::from_amperes(value).to_string();
64        let p = |value, prec| format!("{:.prec$}", Current::from_amperes(value), prec = prec);
65        assert_eq!(s(0.0), "0 mA");
66
67        assert_eq!(s(1.558), "1.558 A");
68        assert_eq!(p(1.558, 1), "1.6 A");
69
70        assert_eq!(s(0.001558), "1.558 mA");
71        assert_eq!(p(0.001558, 1), "1.6 mA");
72
73        assert_eq!(s(1.5508), "1.551 A");
74        assert_eq!(p(1.5508, 5), "1.5508 A");
75
76        assert_eq!(s(0.0015508), "1.551 mA");
77        assert_eq!(p(0.0015508, 5), "1.5508 mA");
78
79        assert_eq!(s(-1.558), "-1.558 A");
80        assert_eq!(p(-1.558, 1), "-1.6 A");
81
82        assert_eq!(s(-0.001558), "-1.558 mA");
83        assert_eq!(p(-0.001558, 1), "-1.6 mA");
84
85        assert_eq!(s(-2030.04487), "-2030.045 A");
86        assert_eq!(p(-2030.04487, 1), "-2030 A");
87        assert_eq!(p(-2030.04487, 2), "-2030.04 A");
88    }
89}