reda_unit/unit/
units.rs

1use super::{Unit, UnitNumber, UnitComplex};
2use paste::paste;
3
4macro_rules! define_unit {
5    ($name:ident, $symbol:literal) => {
6        paste! {
7            #[derive(Debug, PartialEq, Eq, Clone, Copy)]
8            pub struct [<$name Unit>];
9
10            impl Unit for [<$name Unit>] {
11                fn name() -> &'static str {
12                    $symbol
13                }
14            }
15
16            pub type $name = UnitNumber<[<$name Unit>]>;
17            pub type [<$name Phasor>] = UnitComplex<[<$name Unit>]>;
18        }
19    };
20}
21
22define_unit!(Voltage, "V");
23define_unit!(Current, "A");
24define_unit!(Resistance, "Ω");
25define_unit!(Capacitance, "F");
26define_unit!(Inductance, "H");
27define_unit!(Charge, "Q");
28define_unit!(Power, "W");
29define_unit!(Energy, "J");
30define_unit!(Time, "s");
31define_unit!(Frequency, "Hz");
32define_unit!(Length, "m");
33define_unit!(Area, "m²");
34define_unit!(Force, "N");
35define_unit!(Pressure, "Pa");
36define_unit!(MagneticFlux, "Wb");
37define_unit!(FluxDensity, "T");
38define_unit!(Conductance, "S");
39define_unit!(Velocity, "m/s");
40define_unit!(Accel, "m/s²");
41define_unit!(Temperature, "K");
42define_unit!(Angle, "rad");
43
44#[cfg(test)]
45mod tests {
46    use std::str::FromStr;
47
48    use crate::{i, num, r, u, vel};
49
50    use super::*;
51
52    #[test]
53    fn test_voltage_parsing() {
54        let v = Voltage::from_str("5.6V").unwrap();
55        assert_eq!(v.number, num!(5.6));
56
57        let v = Voltage::from_str("3.3mV").unwrap();
58        assert_eq!(v.number, num!(3.3 m));
59    }
60
61    #[test]
62    fn test_resistance_parsing() {
63        let r = Resistance::from_str("10Ω").unwrap();
64        assert_eq!(r.number, num!(10));
65
66        let r = Resistance::from_str("2.2KΩ").unwrap();
67        assert_eq!(r.number, num!(2.2 k));
68    }
69
70    #[test]
71    fn test_invalid_unit() {
72        let result = Voltage::from_str("5.6A");
73        assert!(result.is_err());
74        assert_eq!(result.unwrap_err(), "Expect end with 'V'");
75    }
76
77    #[test]
78    fn test_unit_with_whitespace() {
79        let v = Voltage::from_str("  1.2uV ").unwrap();
80        assert_eq!(v.number, num!(1.2 u));
81    }
82
83    #[test]
84    fn test_same_unit_add_sub() {
85        let q1 = u!(10. mQ); 
86        let q2 = u!(5.0 mQ);
87        let q3 = q1 + q2;
88        assert_eq!(format!("{:.1}", q3), "15.0mQ");
89
90        let t1 = u!(2. us); 
91        let t2 = u!(3. us);
92        let t3 = t2 - t1;
93        assert_eq!(format!("{:.0}", t3), "1us");
94
95        let v1 = u!(1.5 V);
96        let v2 = u!(0.5 V);
97        assert_eq!((v1 + v2).to_string(), "2V");
98
99        let i1 = u!(1 A);
100        let i2 = u!(0.1 A);
101        assert_eq!(format!("{:.2}", i1 - i2), "900.00mA");
102
103        let r1 = u!(100. Ω);
104        let r2 = u!(200. Ω);
105        assert_eq!((r1 + r2).to_string(), "300Ω");
106
107        let c1 = u!(10.0 F);
108        let c2 = u!(5.0 F);
109        assert_eq!(format!("{:.0}", c1 - c2), "5F");
110
111        let e1 = u!(1.2 J);
112        let e2 = u!(0.8 J);
113        assert_eq!((e1 + e2).to_string(), "2J");
114
115        let f1 = u!(9.8 N);
116        let f2 = u!(0.2 N);
117        assert_eq!(format!("{:.1}", f1 - f2), "9.6N");
118
119        let t1 = u!(300. K);
120        let t2 = u!(273. K);
121        assert_eq!(format!("{:.0}", t1 - t2), "27K");
122
123        let a1 = u!(1. rad);
124        let a2 = u!(2. rad);
125        assert_eq!((a1 + a2).to_string(), "3rad");
126    }
127
128    #[test]
129    fn test_display_default() {
130        let v = Voltage::new(3.1415926);
131        assert_eq!(v.to_string(), "3.1415926V");
132
133        let i = Current::new(0.005);
134        assert_eq!(i.to_string(), "0.005A");
135
136        let r = Resistance::new(220.0);
137        assert_eq!(r.to_string(), "220Ω");
138    }
139
140    #[test]
141    fn test_display_precision() {
142        let v = Voltage::new(3.1415926);
143        assert_eq!(format!("{:.2}", v), "3.14V");
144        assert_eq!(format!("{:.4}", v), "3.1416V");
145
146        let i = Current::new(0.0001234);
147        assert_eq!(format!("{:.6}", i), "0.000123A");
148    }
149
150    #[test]
151    fn test_display_zero_and_negative() {
152        let v = Voltage::new(0.0);
153        assert_eq!(v.to_string(), "0V");
154
155        let i = Current::new(-1.23);
156        assert_eq!(i.to_string(), "-1.23A");
157    }
158
159    #[test]
160    fn test_display_scientific_values() {
161        let big = Voltage::new(1e6);
162        assert_eq!(format!("{}", big), "1000000V");
163
164        let small = Current::new(1e-9);
165        assert_eq!(format!("{:.2}", small), "0.00A"); // 精度控制仍会影响
166    }
167
168    #[test]
169    fn test_display_various_units() {
170        let e = Energy::new(12.5);
171        assert_eq!(e.to_string(), "12.5J");
172
173        let t = Time::new(0.001);
174        assert_eq!(format!("{:.3}", t), "0.001s");
175
176        let f = Force::new(9.81);
177        assert_eq!(f.to_string(), "9.81N");
178
179        let p = Pressure::new(101325.0);
180        assert_eq!(format!("{:.0}", p), "101325Pa");
181    }
182    
183    #[test]
184    fn test_ohms_law_voltage() {
185        let i = Current::new(num!(2.0));
186        let r = Resistance::new(num!(5.0));
187        let v = r * i;
188        assert_eq!(v.value(), num!(10.0));
189
190        let i = u!(2.0 A);
191        let r = u!(5.0 Ω);
192        let v = r * i;
193        assert_eq!(v.value(), num!(10.0));
194
195        let i = i!(2.0);
196        let r = r!(5.0);
197        let v = r * i;
198        assert_eq!(v.value(), num!(10.0));
199
200        let i = 2.0;
201        let i = u!(i A);
202        let r = r!(5.0);
203        let v = r * i;
204        assert_eq!(v.value(), num!(10.0));
205    }
206
207    #[test]
208    fn test_power_from_voltage_current() {
209        let v = Voltage::new(num!(3.0));
210        let i = Current::new(num!(2.0));
211        let p = v * i;
212        assert_eq!(p.value(), num!(6.0));
213
214        let v = u!(3.0 v);
215        let i = u!(2.0 A);
216        let p = v * i;
217        assert_eq!(p.value(), num!(6.0));
218    }
219
220    #[test]
221    fn test_energy_from_power_time() {
222        let p = Power::new(num!(5.0));
223        let t = Time::new(num!(10.0));
224        let e = p * t;
225        assert_eq!(e.value(), num!(50.0));
226
227        let p = u!(5.0 mW);
228        let t = u!(10. s);
229        let e = p * t;
230        assert_eq!(e.value(), num!(50.0 m));
231    }
232
233    #[test]
234    fn test_charge_from_capacitance_voltage() {
235        let c = Capacitance::new(num!(1.5));
236        let v = Voltage::new(num!(4.0));
237        let q = c * v;
238        assert_eq!(q.value(), num!(6.0));
239
240        let c = u!(1.5 pF);
241        let v = Voltage::new(num!(4.0));
242        let q = c * v;
243        assert_eq!(q.value(), num!(6.0 p));
244    }
245
246    #[test]
247    fn test_current_from_charge_time() {
248        let q = Charge::new(num!(10.0));
249        let t = Time::new(num!(2.0));
250        let i = q / t;
251        assert_eq!(i.value(), num!(5.0));
252
253        let q = u!(10.0 mQ);
254        let t = u!(2. us);
255        let i = q / t;
256        assert_eq!(i.value(), num!(5.0 k));
257    }
258
259    #[test]
260    fn test_power_from_force_velocity() {
261        let f = Force::new(num!(3.0));
262        let v = Velocity::new(num!(4.0));
263        let p = f * v;
264        assert_eq!(p.value(), num!(12.0));
265    }
266
267    #[test]
268    fn test_energy_from_force_length() {
269        let f = Force::new(num!(10.0));
270        let d = Length::new(num!(2.0));
271        let e = f * d;
272        assert_eq!(e.value(), num!(20.0));
273    }
274
275    #[test]
276    fn test_velocity_time() {
277        let v = vel!(100);
278        let t = u!(5 s);
279        let s = v * t;
280        assert_eq!(s, u!(500 m));
281
282        let v = vel!(100);
283        let t = u!(5 s);
284        let s = v * t;
285        assert_eq!(s, u!(500 m));
286    }
287
288    #[test]
289    fn test_pressure_from_force_area() {
290        let f = Force::new(num!(100.0));
291        let a = Area::new(num!(5.0));
292        let p = f / a;
293        assert_eq!(p.value(), num!(20.0));
294    }
295
296    #[test]
297    fn test_flux_from_density_area() {
298        let b = FluxDensity::new(num!(2.0));
299        let a = Area::new(num!(3.0));
300        let phi = b * a;
301        assert_eq!(phi.value(), num!(6.0));
302    }
303
304    #[test]
305    fn test_serialize_deserialize_unit_voltage() {
306        let v = Voltage::from_str("5.0V").unwrap();
307        let json = serde_json::to_string(&v).unwrap();
308        assert_eq!(json, "\"5V\"");
309        let parsed: Voltage = serde_json::from_str(&json).unwrap();
310        assert_eq!(parsed, v);
311    }
312
313    #[test]
314    fn test_serialize_deserialize_unit_current() {
315        let i = Current::from_str("2.2mA").unwrap();
316        let json = serde_json::to_string(&i).unwrap();
317        assert_eq!(json, "\"2.2mA\"");
318        let parsed: Current = serde_json::from_str(&json).unwrap();
319        assert_eq!(parsed, i);
320    }
321
322    #[test]
323    fn test_serialize_deserialize_unit_unicode() {
324        let r = Resistance::from_str("10kΩ").unwrap();
325        let json = serde_json::to_string(&r).unwrap();
326        assert_eq!(json, "\"10KΩ\"");
327        let parsed: Resistance = serde_json::from_str(&json).unwrap();
328        assert_eq!(parsed, r);
329    }
330
331    #[test]
332    fn test_deserialize_invalid_unit() {
333        let result: Result<Voltage, _> = serde_json::from_str("\"3.3A\""); // 单位错了
334        assert!(result.is_err());
335    }
336
337    #[test]
338    fn test_div_self() {
339        let t1 = u!(100 s);
340        let t2 = u!(100 s);
341        let s = t1 / t2;
342        assert_eq!(s, num!(1))
343    }
344}