1use serde::{Deserialize, Serialize};
4
5use crate::enums::{Currency, Unit};
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8#[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 #[serde(flatten)]
30 pub meta: Bo4eMeta,
31
32 #[serde(skip_serializing_if = "Option::is_none")]
34 #[cfg_attr(feature = "json-schema", schemars(rename = "bezeichnung"))]
35 pub description: Option<String>,
36
37 #[serde(skip_serializing_if = "Option::is_none")]
39 #[cfg_attr(feature = "json-schema", schemars(rename = "wert"))]
40 pub value: Option<f64>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 #[cfg_attr(feature = "json-schema", schemars(rename = "waehrung"))]
45 pub currency: Option<Currency>,
46
47 #[serde(skip_serializing_if = "Option::is_none")]
49 #[cfg_attr(feature = "json-schema", schemars(rename = "bezugseinheit"))]
50 pub reference_unit: Option<Unit>,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
54 #[cfg_attr(feature = "json-schema", schemars(rename = "gesetzlicheGrundlage"))]
55 pub legal_reference: Option<String>,
56
57 #[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}