bo4e_core/bo/
market_location.rs1use serde::{Deserialize, Serialize};
6
7use crate::com::Address;
8use crate::enums::{CustomerType, Division, EnergyDirection};
9use crate::traits::{Bo4eMeta, Bo4eObject};
10
11#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
33#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
34#[cfg_attr(feature = "json-schema", schemars(rename = "Marktlokation"))]
35#[serde(rename_all = "camelCase")]
36pub struct MarketLocation {
37 #[serde(flatten)]
39 pub meta: Bo4eMeta,
40
41 #[serde(skip_serializing_if = "Option::is_none", alias = "marktlokationsId")]
43 #[cfg_attr(feature = "json-schema", schemars(rename = "marktlokationsId"))]
44 pub market_location_id: Option<String>,
45
46 #[serde(skip_serializing_if = "Option::is_none", alias = "sparte")]
48 #[cfg_attr(feature = "json-schema", schemars(rename = "sparte"))]
49 pub division: Option<Division>,
50
51 #[serde(skip_serializing_if = "Option::is_none", alias = "energierichtung")]
53 #[cfg_attr(feature = "json-schema", schemars(rename = "energierichtung"))]
54 pub energy_direction: Option<EnergyDirection>,
55
56 #[serde(skip_serializing_if = "Option::is_none", alias = "kundentyp")]
58 #[cfg_attr(feature = "json-schema", schemars(rename = "kundentyp"))]
59 pub customer_type: Option<CustomerType>,
60
61 #[serde(skip_serializing_if = "Option::is_none", alias = "adresse")]
63 #[cfg_attr(feature = "json-schema", schemars(rename = "adresse"))]
64 pub address: Option<Address>,
65
66 #[serde(skip_serializing_if = "Option::is_none", alias = "lieferbeginn")]
68 #[cfg_attr(feature = "json-schema", schemars(rename = "lieferbeginn"))]
69 pub supply_start: Option<chrono::DateTime<chrono::Utc>>,
70
71 #[serde(skip_serializing_if = "Option::is_none", alias = "lieferende")]
73 #[cfg_attr(feature = "json-schema", schemars(rename = "lieferende"))]
74 pub supply_end: Option<chrono::DateTime<chrono::Utc>>,
75
76 #[serde(
78 skip_serializing_if = "Option::is_none",
79 alias = "jahresverbrauchsprognose"
80 )]
81 #[cfg_attr(feature = "json-schema", schemars(rename = "jahresverbrauchsprognose"))]
82 pub annual_consumption: Option<f64>,
83
84 #[serde(
86 skip_serializing_if = "Option::is_none",
87 alias = "netzbetreiberCodenummer"
88 )]
89 #[cfg_attr(feature = "json-schema", schemars(rename = "netzbetreiberCodenummer"))]
90 pub network_operator_code: Option<String>,
91
92 #[serde(
94 skip_serializing_if = "Option::is_none",
95 alias = "grundversorgerCodenummer"
96 )]
97 #[cfg_attr(feature = "json-schema", schemars(rename = "grundversorgerCodenummer"))]
98 pub basic_supplier_code: Option<String>,
99
100 #[serde(
102 skip_serializing_if = "Option::is_none",
103 alias = "messstellenbetreiberCodenummer"
104 )]
105 #[cfg_attr(
106 feature = "json-schema",
107 schemars(rename = "messstellenbetreiberCodenummer")
108 )]
109 pub metering_operator_code: Option<String>,
110
111 #[serde(
113 skip_serializing_if = "Option::is_none",
114 alias = "uebertragungsnetzbetreiberCodenummer"
115 )]
116 #[cfg_attr(
117 feature = "json-schema",
118 schemars(rename = "uebertragungsnetzbetreiberCodenummer")
119 )]
120 pub transmission_operator_code: Option<String>,
121
122 #[serde(skip_serializing_if = "Option::is_none", alias = "netzebene")]
124 #[cfg_attr(feature = "json-schema", schemars(rename = "netzebene"))]
125 pub grid_level: Option<String>,
126
127 #[serde(skip_serializing_if = "Option::is_none", alias = "netzgebiet")]
129 #[cfg_attr(feature = "json-schema", schemars(rename = "netzgebiet"))]
130 pub network_area: Option<String>,
131
132 #[serde(skip_serializing_if = "Option::is_none", alias = "bilanzierungsgebiet")]
134 #[cfg_attr(feature = "json-schema", schemars(rename = "bilanzierungsgebiet"))]
135 pub balancing_area: Option<String>,
136
137 #[serde(
139 default,
140 skip_serializing_if = "Vec::is_empty",
141 alias = "messlokationsIds"
142 )]
143 #[cfg_attr(feature = "json-schema", schemars(rename = "messlokationsIds"))]
144 pub metering_location_ids: Vec<String>,
145
146 #[serde(
148 skip_serializing_if = "Option::is_none",
149 alias = "istSteuerbareRessource"
150 )]
151 #[cfg_attr(feature = "json-schema", schemars(rename = "istSteuerbareRessource"))]
152 pub is_controllable_resource: Option<bool>,
153}
154
155impl Bo4eObject for MarketLocation {
156 fn type_name_german() -> &'static str {
157 "Marktlokation"
158 }
159
160 fn type_name_english() -> &'static str {
161 "MarketLocation"
162 }
163
164 fn meta(&self) -> &Bo4eMeta {
165 &self.meta
166 }
167
168 fn meta_mut(&mut self) -> &mut Bo4eMeta {
169 &mut self.meta
170 }
171}
172
173#[cfg(test)]
174mod tests {
175 use super::*;
176
177 #[test]
178 fn test_malo_id_format() {
179 let malo = MarketLocation {
181 market_location_id: Some("12345678901".to_string()),
182 division: Some(Division::Electricity),
183 energy_direction: Some(EnergyDirection::FeedOut),
184 ..Default::default()
185 };
186
187 assert_eq!(malo.market_location_id.as_ref().unwrap().len(), 11);
188 }
189
190 #[test]
191 fn test_serialize() {
192 let malo = MarketLocation {
193 meta: Bo4eMeta::with_type("Marktlokation"),
194 market_location_id: Some("12345678901".to_string()),
195 ..Default::default()
196 };
197
198 let json = serde_json::to_string(&malo).unwrap();
199 assert!(json.contains(r#""marketLocationId":"12345678901""#));
200 }
201
202 #[test]
203 fn test_roundtrip() {
204 let malo = MarketLocation {
205 meta: Bo4eMeta::with_type("Marktlokation"),
206 market_location_id: Some("12345678901".to_string()),
207 division: Some(Division::Electricity),
208 energy_direction: Some(EnergyDirection::FeedOut),
209 annual_consumption: Some(3500.0),
210 metering_location_ids: vec!["DE00012345".to_string()],
211 ..Default::default()
212 };
213
214 let json = serde_json::to_string(&malo).unwrap();
215 let parsed: MarketLocation = serde_json::from_str(&json).unwrap();
216 assert_eq!(malo, parsed);
217 }
218
219 #[test]
220 fn test_bo4e_object_impl() {
221 assert_eq!(MarketLocation::type_name_german(), "Marktlokation");
222 assert_eq!(MarketLocation::type_name_english(), "MarketLocation");
223 }
224}