konduto/types/address/
mod.rs1use serde::{Deserialize, Serialize};
2mod address_line;
3mod address_name;
4mod city;
5mod country_code;
6mod state;
7mod zip_code;
8
9pub use address_line::AddressLine;
10pub use address_name::AddressName;
11pub use city::City;
12pub use country_code::{Country, CountryCode};
13pub use state::State;
14pub use zip_code::ZipCode;
15
16#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
18pub struct Address {
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub name: Option<AddressName>,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub address1: Option<AddressLine>,
26
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub address2: Option<AddressLine>,
30
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub city: Option<City>,
34
35 #[serde(skip_serializing_if = "Option::is_none")]
37 pub state: Option<State>,
38
39 #[serde(skip_serializing_if = "Option::is_none")]
41 pub zip: Option<ZipCode>,
42
43 #[serde(skip_serializing_if = "Option::is_none")]
45 pub country: Option<Country>,
46}
47
48impl Address {
49 pub fn builder() -> AddressBuilder {
51 AddressBuilder::default()
52 }
53}
54
55#[derive(Default)]
57pub struct AddressBuilder {
58 address: Address,
59}
60
61impl AddressBuilder {
62 pub fn name(
64 mut self,
65 name: impl Into<String>,
66 ) -> Result<Self, crate::types::validation_errors::ValidationError> {
67 self.address.name = Some(AddressName::try_new(name)?);
68 Ok(self)
69 }
70
71 pub fn address1(
73 mut self,
74 address: impl Into<String>,
75 ) -> Result<Self, crate::types::validation_errors::ValidationError> {
76 self.address.address1 = Some(AddressLine::try_new(address)?);
77 Ok(self)
78 }
79
80 pub fn address2(
82 mut self,
83 address: impl Into<String>,
84 ) -> Result<Self, crate::types::validation_errors::ValidationError> {
85 self.address.address2 = Some(AddressLine::try_new(address)?);
86 Ok(self)
87 }
88
89 pub fn city(
91 mut self,
92 city: impl Into<String>,
93 ) -> Result<Self, crate::types::validation_errors::ValidationError> {
94 self.address.city = Some(City::try_new(city)?);
95 Ok(self)
96 }
97
98 pub fn state(
100 mut self,
101 state: impl Into<String>,
102 ) -> Result<Self, crate::types::validation_errors::ValidationError> {
103 self.address.state = Some(State::try_new(state)?);
104 Ok(self)
105 }
106
107 pub fn zip(
109 mut self,
110 zip: impl Into<String>,
111 ) -> Result<Self, crate::types::validation_errors::ValidationError> {
112 self.address.zip = Some(ZipCode::try_new(zip)?);
113 Ok(self)
114 }
115
116 pub fn country(mut self, country: Country) -> Self {
118 self.address.country = Some(country);
119 self
120 }
121
122 pub fn build(self) -> Address {
124 self.address
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn test_address_builder() -> Result<(), Box<dyn std::error::Error>> {
134 let address = Address::builder()
135 .name("John Doe")?
136 .address1("123 Main St")?
137 .city("São Paulo")?
138 .state("SP")?
139 .zip("01234-567")?
140 .country(Country::BR)
141 .build();
142
143 assert!(address.name.is_some());
144 assert!(address.address1.is_some());
145 assert!(address.city.is_some());
146 assert_eq!(address.country, Some(Country::BR));
147 Ok(())
148 }
149
150 #[test]
151 fn test_address_serialization() -> Result<(), Box<dyn std::error::Error>> {
152 let address = Address::builder()
153 .name("Jane Doe")?
154 .address1("456 Oak Ave")?
155 .city("Rio de Janeiro")?
156 .state("RJ")?
157 .zip("20000-000")?
158 .country(Country::BR)
159 .build();
160
161 let json = serde_json::to_string(&address).unwrap();
162 assert!(json.contains("Jane Doe"));
163 assert!(json.contains("Rio de Janeiro"));
164 Ok(())
165 }
166
167 #[test]
168 fn test_address_default() {
169 let address = Address::default();
170 assert!(address.name.is_none());
171 assert!(address.address1.is_none());
172 }
173
174 #[test]
175 fn test_invalid_country_code() {
176 let result = Country::from_code("USA"); assert!(result.is_err());
178 }
179
180 #[test]
181 fn test_name_too_long() {
182 let long_name = "a".repeat(101);
183 let result = AddressName::try_new(long_name);
184 assert!(result.is_err());
185 }
186
187 #[test]
188 fn test_address_line_too_long() {
189 let long_address = "a".repeat(256);
190 let result = AddressLine::try_new(long_address);
191 assert!(result.is_err());
192 }
193}