Skip to main content

bo4e_core/com/
levy.rs

1//! Levy (Umlage) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::enums::{Currency, Unit};
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// A levy such as EEG, KWK, etc.
9///
10/// German: Umlage
11///
12/// # Example
13///
14/// ```rust
15/// use bo4e_core::com::Levy;
16///
17/// let levy = Levy {
18///     description: Some("EEG-Umlage".to_string()),
19///     value: Some(6.756),
20///     ..Default::default()
21/// };
22/// ```
23#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
24#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
25#[cfg_attr(feature = "json-schema", schemars(rename = "Umlage"))]
26#[serde(rename_all = "camelCase")]
27pub struct Levy {
28    /// BO4E metadata
29    #[serde(flatten)]
30    pub meta: Bo4eMeta,
31
32    /// Description/name of the levy (Bezeichnung)
33    #[serde(skip_serializing_if = "Option::is_none")]
34    #[cfg_attr(feature = "json-schema", schemars(rename = "bezeichnung"))]
35    pub description: Option<String>,
36
37    /// Levy value (Wert)
38    #[serde(skip_serializing_if = "Option::is_none")]
39    #[cfg_attr(feature = "json-schema", schemars(rename = "wert"))]
40    pub value: Option<f64>,
41
42    /// Currency (Waehrung)
43    #[serde(skip_serializing_if = "Option::is_none")]
44    #[cfg_attr(feature = "json-schema", schemars(rename = "waehrung"))]
45    pub currency: Option<Currency>,
46
47    /// Reference unit (Bezugseinheit)
48    #[serde(skip_serializing_if = "Option::is_none")]
49    #[cfg_attr(feature = "json-schema", schemars(rename = "bezugseinheit"))]
50    pub reference_unit: Option<Unit>,
51
52    /// Legal reference (Gesetzliche Grundlage)
53    #[serde(skip_serializing_if = "Option::is_none")]
54    #[cfg_attr(feature = "json-schema", schemars(rename = "gesetzlicheGrundlage"))]
55    pub legal_reference: Option<String>,
56
57    /// Website for more information (Website)
58    #[serde(skip_serializing_if = "Option::is_none")]
59    #[cfg_attr(feature = "json-schema", schemars(rename = "website"))]
60    pub website: Option<String>,
61}
62
63impl Bo4eObject for Levy {
64    fn type_name_german() -> &'static str {
65        "Umlage"
66    }
67
68    fn type_name_english() -> &'static str {
69        "Levy"
70    }
71
72    fn meta(&self) -> &Bo4eMeta {
73        &self.meta
74    }
75
76    fn meta_mut(&mut self) -> &mut Bo4eMeta {
77        &mut self.meta
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn test_eeg_levy() {
87        let levy = Levy {
88            description: Some("EEG-Umlage".to_string()),
89            value: Some(6.756),
90            currency: Some(Currency::Eur),
91            reference_unit: Some(Unit::KilowattHour),
92            legal_reference: Some("§ 60 EEG".to_string()),
93            ..Default::default()
94        };
95
96        assert_eq!(levy.description, Some("EEG-Umlage".to_string()));
97        assert_eq!(levy.value, Some(6.756));
98    }
99
100    #[test]
101    fn test_kwk_levy() {
102        let levy = Levy {
103            description: Some("KWK-Umlage".to_string()),
104            value: Some(0.254),
105            currency: Some(Currency::Eur),
106            reference_unit: Some(Unit::KilowattHour),
107            ..Default::default()
108        };
109
110        assert_eq!(levy.description, Some("KWK-Umlage".to_string()));
111    }
112
113    #[test]
114    fn test_default() {
115        let levy = Levy::default();
116        assert!(levy.description.is_none());
117        assert!(levy.value.is_none());
118    }
119
120    #[test]
121    fn test_roundtrip() {
122        let levy = Levy {
123            description: Some("§19 StromNEV-Umlage".to_string()),
124            value: Some(0.437),
125            currency: Some(Currency::Eur),
126            reference_unit: Some(Unit::KilowattHour),
127            legal_reference: Some("§ 19 StromNEV".to_string()),
128            website: Some("https://www.netztransparenz.de".to_string()),
129            ..Default::default()
130        };
131
132        let json = serde_json::to_string(&levy).unwrap();
133        let parsed: Levy = serde_json::from_str(&json).unwrap();
134        assert_eq!(levy, parsed);
135    }
136
137    #[test]
138    fn test_bo4e_object_impl() {
139        assert_eq!(Levy::type_name_german(), "Umlage");
140        assert_eq!(Levy::type_name_english(), "Levy");
141    }
142}