Skip to main content

bo4e_core/com/
network_charge.rs

1//! Network charge (Netzentgelt) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::enums::{Currency, PriceType, Unit};
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// A network charge/fee component.
9///
10/// German: Netzentgelt
11///
12/// # Example
13///
14/// ```rust
15/// use bo4e_core::com::NetworkCharge;
16/// use bo4e_core::enums::PriceType;
17///
18/// let charge = NetworkCharge {
19///     price_type: Some(PriceType::WorkingPriceSingleTariff),
20///     value: Some(5.82),
21///     ..Default::default()
22/// };
23/// ```
24#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
25#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
26#[cfg_attr(feature = "json-schema", schemars(rename = "Netzentgelt"))]
27#[serde(rename_all = "camelCase")]
28pub struct NetworkCharge {
29    /// BO4E metadata
30    #[serde(flatten)]
31    pub meta: Bo4eMeta,
32
33    /// Type of price (Preistyp)
34    #[serde(skip_serializing_if = "Option::is_none")]
35    #[cfg_attr(feature = "json-schema", schemars(rename = "preistyp"))]
36    pub price_type: Option<PriceType>,
37
38    /// Charge value (Wert)
39    #[serde(skip_serializing_if = "Option::is_none")]
40    #[cfg_attr(feature = "json-schema", schemars(rename = "wert"))]
41    pub value: Option<f64>,
42
43    /// Currency (Waehrung)
44    #[serde(skip_serializing_if = "Option::is_none")]
45    #[cfg_attr(feature = "json-schema", schemars(rename = "waehrung"))]
46    pub currency: Option<Currency>,
47
48    /// Reference unit (Bezugseinheit)
49    #[serde(skip_serializing_if = "Option::is_none")]
50    #[cfg_attr(feature = "json-schema", schemars(rename = "bezugseinheit"))]
51    pub reference_unit: Option<Unit>,
52
53    /// Description (Beschreibung)
54    #[serde(skip_serializing_if = "Option::is_none")]
55    #[cfg_attr(feature = "json-schema", schemars(rename = "beschreibung"))]
56    pub description: Option<String>,
57
58    /// Network operator code (Netzbetreiber)
59    #[serde(skip_serializing_if = "Option::is_none")]
60    #[cfg_attr(feature = "json-schema", schemars(rename = "netzbetreiber"))]
61    pub network_operator_code: Option<String>,
62}
63
64impl Bo4eObject for NetworkCharge {
65    fn type_name_german() -> &'static str {
66        "Netzentgelt"
67    }
68
69    fn type_name_english() -> &'static str {
70        "NetworkCharge"
71    }
72
73    fn meta(&self) -> &Bo4eMeta {
74        &self.meta
75    }
76
77    fn meta_mut(&mut self) -> &mut Bo4eMeta {
78        &mut self.meta
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn test_work_price_charge() {
88        let charge = NetworkCharge {
89            price_type: Some(PriceType::WorkingPriceSingleTariff),
90            value: Some(5.82),
91            currency: Some(Currency::Eur),
92            reference_unit: Some(Unit::KilowattHour),
93            ..Default::default()
94        };
95
96        assert_eq!(charge.price_type, Some(PriceType::WorkingPriceSingleTariff));
97        assert_eq!(charge.value, Some(5.82));
98    }
99
100    #[test]
101    fn test_base_price_charge() {
102        let charge = NetworkCharge {
103            price_type: Some(PriceType::BasePrice),
104            value: Some(55.0),
105            currency: Some(Currency::Eur),
106            reference_unit: Some(Unit::Year),
107            network_operator_code: Some("9900001".to_string()),
108            ..Default::default()
109        };
110
111        assert_eq!(charge.price_type, Some(PriceType::BasePrice));
112    }
113
114    #[test]
115    fn test_default() {
116        let charge = NetworkCharge::default();
117        assert!(charge.price_type.is_none());
118        assert!(charge.value.is_none());
119    }
120
121    #[test]
122    fn test_roundtrip() {
123        let charge = NetworkCharge {
124            price_type: Some(PriceType::WorkingPriceSingleTariff),
125            value: Some(6.25),
126            currency: Some(Currency::Eur),
127            reference_unit: Some(Unit::KilowattHour),
128            description: Some("Arbeitspreis Netznutzung".to_string()),
129            ..Default::default()
130        };
131
132        let json = serde_json::to_string(&charge).unwrap();
133        let parsed: NetworkCharge = serde_json::from_str(&json).unwrap();
134        assert_eq!(charge, parsed);
135    }
136
137    #[test]
138    fn test_bo4e_object_impl() {
139        assert_eq!(NetworkCharge::type_name_german(), "Netzentgelt");
140        assert_eq!(NetworkCharge::type_name_english(), "NetworkCharge");
141    }
142}