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