1use serde::{Deserialize, Serialize};
4
5use crate::enums::Country;
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
26#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
27#[cfg_attr(feature = "json-schema", schemars(rename = "Adresse"))]
28#[serde(rename_all = "camelCase")]
29pub struct Address {
30 #[serde(flatten)]
32 pub meta: Bo4eMeta,
33
34 #[serde(skip_serializing_if = "Option::is_none", alias = "strasse")]
36 #[cfg_attr(feature = "json-schema", schemars(rename = "strasse"))]
37 pub street: Option<String>,
38
39 #[serde(skip_serializing_if = "Option::is_none", alias = "hausnummer")]
41 #[cfg_attr(feature = "json-schema", schemars(rename = "hausnummer"))]
42 pub house_number: Option<String>,
43
44 #[serde(skip_serializing_if = "Option::is_none", alias = "postleitzahl")]
46 #[cfg_attr(feature = "json-schema", schemars(rename = "postleitzahl"))]
47 pub postal_code: Option<String>,
48
49 #[serde(skip_serializing_if = "Option::is_none", alias = "ort")]
51 #[cfg_attr(feature = "json-schema", schemars(rename = "ort"))]
52 pub city: Option<String>,
53
54 #[serde(skip_serializing_if = "Option::is_none", alias = "ortsteil")]
56 #[cfg_attr(feature = "json-schema", schemars(rename = "ortsteil"))]
57 pub district: Option<String>,
58
59 #[serde(skip_serializing_if = "Option::is_none", alias = "postfach")]
61 #[cfg_attr(feature = "json-schema", schemars(rename = "postfach"))]
62 pub po_box: Option<String>,
63
64 #[serde(skip_serializing_if = "Option::is_none", alias = "adresszusatz")]
66 #[cfg_attr(feature = "json-schema", schemars(rename = "adresszusatz"))]
67 pub address_addition: Option<String>,
68
69 #[serde(skip_serializing_if = "Option::is_none", alias = "coErgaenzung")]
71 #[cfg_attr(feature = "json-schema", schemars(rename = "coErgaenzung"))]
72 pub co_ergaenzung: Option<String>,
73
74 #[serde(skip_serializing_if = "Option::is_none", alias = "landescode")]
76 #[cfg_attr(feature = "json-schema", schemars(rename = "landescode"))]
77 pub country_code: Option<Country>,
78}
79
80impl Bo4eObject for Address {
81 fn type_name_german() -> &'static str {
82 "Adresse"
83 }
84
85 fn type_name_english() -> &'static str {
86 "Address"
87 }
88
89 fn meta(&self) -> &Bo4eMeta {
90 &self.meta
91 }
92
93 fn meta_mut(&mut self) -> &mut Bo4eMeta {
94 &mut self.meta
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_address_default() {
104 let address = Address::default();
105 assert!(address.street.is_none());
106 assert!(address.city.is_none());
107 }
108
109 #[test]
110 fn test_address_serialize() {
111 let address = Address {
112 street: Some("Hauptstraße".to_string()),
113 house_number: Some("1".to_string()),
114 postal_code: Some("12345".to_string()),
115 city: Some("Berlin".to_string()),
116 ..Default::default()
117 };
118
119 let json = serde_json::to_string(&address).unwrap();
120 assert!(json.contains(r#""street":"Hauptstraße""#));
121 assert!(json.contains(r#""houseNumber":"1""#));
122 assert!(json.contains(r#""postalCode":"12345""#));
123 assert!(json.contains(r#""city":"Berlin""#));
124 }
125
126 #[test]
127 fn test_address_deserialize() {
128 let json = r#"{
129 "street": "Musterweg",
130 "houseNumber": "42a",
131 "postalCode": "50667",
132 "city": "Köln"
133 }"#;
134
135 let address: Address = serde_json::from_str(json).unwrap();
136 assert_eq!(address.street, Some("Musterweg".to_string()));
137 assert_eq!(address.house_number, Some("42a".to_string()));
138 assert_eq!(address.postal_code, Some("50667".to_string()));
139 assert_eq!(address.city, Some("Köln".to_string()));
140 }
141
142 #[test]
143 fn test_address_roundtrip() {
144 let address = Address {
145 meta: Bo4eMeta::with_type("Adresse"),
146 street: Some("Teststraße".to_string()),
147 house_number: Some("123".to_string()),
148 postal_code: Some("99999".to_string()),
149 city: Some("Teststadt".to_string()),
150 ..Default::default()
151 };
152
153 let json = serde_json::to_string(&address).unwrap();
154 let parsed: Address = serde_json::from_str(&json).unwrap();
155 assert_eq!(address, parsed);
156 }
157
158 #[test]
159 fn test_address_with_country() {
160 let address = Address {
161 street: Some("Musterstraße".to_string()),
162 city: Some("München".to_string()),
163 country_code: Some(Country::Germany),
164 ..Default::default()
165 };
166
167 let json = serde_json::to_string(&address).unwrap();
168 assert!(json.contains(r#""countryCode":"DE""#));
169
170 let parsed: Address = serde_json::from_str(&json).unwrap();
171 assert_eq!(parsed.country_code, Some(Country::Germany));
172 }
173
174 #[test]
175 fn test_bo4e_object_impl() {
176 assert_eq!(Address::type_name_german(), "Adresse");
177 assert_eq!(Address::type_name_english(), "Address");
178 }
179}