bo4e_core/com/
consumed_quantity.rs

1//! Consumed quantity (VerbrauchteQuantitaet) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::enums::Unit;
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// A consumed quantity with value and unit.
9///
10/// German: VerbrauchteQuantitaet
11///
12/// # Example
13///
14/// ```rust
15/// use bo4e_core::com::ConsumedQuantity;
16/// use bo4e_core::enums::Unit;
17///
18/// let quantity = ConsumedQuantity {
19///     value: Some(3500.0),
20///     unit: Some(Unit::KilowattHour),
21///     ..Default::default()
22/// };
23/// ```
24#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
25#[serde(rename_all = "camelCase")]
26pub struct ConsumedQuantity {
27    /// BO4E metadata
28    #[serde(flatten)]
29    pub meta: Bo4eMeta,
30
31    /// The quantity value (Wert)
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub value: Option<f64>,
34
35    /// Unit of measurement (Einheit)
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub unit: Option<Unit>,
38}
39
40impl Bo4eObject for ConsumedQuantity {
41    fn type_name_german() -> &'static str {
42        "VerbrauchteQuantitaet"
43    }
44
45    fn type_name_english() -> &'static str {
46        "ConsumedQuantity"
47    }
48
49    fn meta(&self) -> &Bo4eMeta {
50        &self.meta
51    }
52
53    fn meta_mut(&mut self) -> &mut Bo4eMeta {
54        &mut self.meta
55    }
56}
57
58impl ConsumedQuantity {
59    /// Create a quantity in kWh.
60    pub fn kwh(value: f64) -> Self {
61        Self {
62            value: Some(value),
63            unit: Some(Unit::KilowattHour),
64            ..Default::default()
65        }
66    }
67
68    /// Create a quantity in cubic meters.
69    pub fn cubic_meters(value: f64) -> Self {
70        Self {
71            value: Some(value),
72            unit: Some(Unit::CubicMeter),
73            ..Default::default()
74        }
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn test_kwh_quantity() {
84        let quantity = ConsumedQuantity::kwh(3500.0);
85        assert_eq!(quantity.value, Some(3500.0));
86        assert_eq!(quantity.unit, Some(Unit::KilowattHour));
87    }
88
89    #[test]
90    fn test_cubic_meters() {
91        let quantity = ConsumedQuantity::cubic_meters(1250.0);
92        assert_eq!(quantity.value, Some(1250.0));
93        assert_eq!(quantity.unit, Some(Unit::CubicMeter));
94    }
95
96    #[test]
97    fn test_default() {
98        let quantity = ConsumedQuantity::default();
99        assert!(quantity.value.is_none());
100        assert!(quantity.unit.is_none());
101    }
102
103    #[test]
104    fn test_roundtrip() {
105        let quantity = ConsumedQuantity {
106            value: Some(5678.9),
107            unit: Some(Unit::KilowattHour),
108            ..Default::default()
109        };
110
111        let json = serde_json::to_string(&quantity).unwrap();
112        let parsed: ConsumedQuantity = serde_json::from_str(&json).unwrap();
113        assert_eq!(quantity, parsed);
114    }
115
116    #[test]
117    fn test_bo4e_object_impl() {
118        assert_eq!(
119            ConsumedQuantity::type_name_german(),
120            "VerbrauchteQuantitaet"
121        );
122        assert_eq!(ConsumedQuantity::type_name_english(), "ConsumedQuantity");
123    }
124}