bo4e_core/bo/
technical_resource.rs1use serde::{Deserialize, Serialize};
6
7use crate::com::Address;
8use crate::enums::{Division, EnergyDirection, TechnicalResourceUsage};
9use crate::traits::{Bo4eMeta, Bo4eObject};
10
11#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct TechnicalResource {
34 #[serde(flatten)]
36 pub meta: Bo4eMeta,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub technical_resource_id: Option<String>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub division: Option<Division>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub usage: Option<TechnicalResourceUsage>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub energy_direction: Option<EnergyDirection>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub address: Option<Address>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub description: Option<String>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub nominal_power: Option<f64>,
65
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub max_power: Option<f64>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub min_power: Option<f64>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub energy_capacity: Option<f64>,
77
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub metering_location_id: Option<String>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub market_location_id: Option<String>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
88 pub commissioning_date: Option<chrono::DateTime<chrono::Utc>>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub decommissioning_date: Option<chrono::DateTime<chrono::Utc>>,
93}
94
95impl Bo4eObject for TechnicalResource {
96 fn type_name_german() -> &'static str {
97 "TechnischeRessource"
98 }
99
100 fn type_name_english() -> &'static str {
101 "TechnicalResource"
102 }
103
104 fn meta(&self) -> &Bo4eMeta {
105 &self.meta
106 }
107
108 fn meta_mut(&mut self) -> &mut Bo4eMeta {
109 &mut self.meta
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn test_technical_resource_creation() {
119 let resource = TechnicalResource {
120 technical_resource_id: Some("TR001".to_string()),
121 division: Some(Division::Electricity),
122 usage: Some(TechnicalResourceUsage::ElectricityGenerationType),
123 ..Default::default()
124 };
125
126 assert_eq!(resource.technical_resource_id, Some("TR001".to_string()));
127 }
128
129 #[test]
130 fn test_serialize() {
131 let resource = TechnicalResource {
132 meta: Bo4eMeta::with_type("TechnischeRessource"),
133 technical_resource_id: Some("TR001".to_string()),
134 ..Default::default()
135 };
136
137 let json = serde_json::to_string(&resource).unwrap();
138 assert!(json.contains(r#""_typ":"TechnischeRessource""#));
139 }
140
141 #[test]
142 fn test_roundtrip() {
143 let resource = TechnicalResource {
144 meta: Bo4eMeta::with_type("TechnischeRessource"),
145 technical_resource_id: Some("TR001".to_string()),
146 division: Some(Division::Electricity),
147 usage: Some(TechnicalResourceUsage::ElectricityGenerationType),
148 nominal_power: Some(100.0),
149 max_power: Some(120.0),
150 ..Default::default()
151 };
152
153 let json = serde_json::to_string(&resource).unwrap();
154 let parsed: TechnicalResource = serde_json::from_str(&json).unwrap();
155 assert_eq!(resource, parsed);
156 }
157
158 #[test]
159 fn test_bo4e_object_impl() {
160 assert_eq!(TechnicalResource::type_name_german(), "TechnischeRessource");
161 assert_eq!(TechnicalResource::type_name_english(), "TechnicalResource");
162 }
163}