1use crate::provider::{Protocol, Socket};
4
5#[derive(Debug, Clone, PartialEq)]
10pub(crate) struct ServerParams {
11 pub protocol: Protocol,
13
14 pub hostname: String,
16
17 pub port: u16,
19
20 pub socket: Socket,
22
23 pub username: String,
25}
26
27impl ServerParams {
28 fn expand_usernames(self, addr: &str) -> Vec<ServerParams> {
29 if self.username.is_empty() {
30 vec![Self {
31 username: addr.to_string(),
32 ..self.clone()
33 }]
34 } else {
35 vec![self]
36 }
37 }
38
39 fn expand_hostnames(self, param_domain: &str) -> Vec<ServerParams> {
40 if self.hostname.is_empty() {
41 vec![
42 Self {
45 hostname: match self.protocol {
46 Protocol::Imap => "imap.".to_string() + param_domain,
47 Protocol::Smtp => "smtp.".to_string() + param_domain,
48 },
49 ..self.clone()
50 },
51 Self {
52 hostname: "mail.".to_string() + param_domain,
53 ..self.clone()
54 },
55 Self {
58 hostname: param_domain.to_string(),
59 ..self
60 },
61 ]
62 } else {
63 vec![self]
64 }
65 }
66
67 fn expand_ports(mut self) -> Vec<ServerParams> {
68 if self.port == 0 {
70 self.port = match self.socket {
71 Socket::Ssl => match self.protocol {
72 Protocol::Imap => 993,
73 Protocol::Smtp => 465,
74 },
75 Socket::Starttls | Socket::Plain => match self.protocol {
76 Protocol::Imap => 143,
77 Protocol::Smtp => 587,
78 },
79 Socket::Automatic => 0,
80 }
81 }
82
83 if self.port == 0 {
84 vec![
89 Self {
91 socket: Socket::Ssl,
92 port: match self.protocol {
93 Protocol::Imap => 993,
94 Protocol::Smtp => 465,
95 },
96 ..self.clone()
97 },
98 Self {
100 socket: Socket::Starttls,
101 port: match self.protocol {
102 Protocol::Imap => 143,
103 Protocol::Smtp => 587,
104 },
105 ..self
106 },
107 ]
108 } else if self.socket == Socket::Automatic {
109 vec![
110 Self {
112 socket: Socket::Ssl,
113 ..self.clone()
114 },
115 Self {
117 socket: Socket::Starttls,
118 ..self
119 },
120 ]
121 } else {
122 vec![self]
123 }
124 }
125}
126
127pub(crate) fn expand_param_vector(
130 v: Vec<ServerParams>,
131 addr: &str,
132 domain: &str,
133) -> Vec<ServerParams> {
134 v.into_iter()
135 .flat_map(|params| params.expand_usernames(addr).into_iter())
139 .flat_map(|params| params.expand_hostnames(domain).into_iter())
140 .flat_map(|params| params.expand_ports().into_iter())
141 .collect()
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_expand_param_vector() {
150 let v = expand_param_vector(
151 vec![ServerParams {
152 protocol: Protocol::Imap,
153 hostname: "example.net".to_string(),
154 port: 0,
155 socket: Socket::Ssl,
156 username: "foobar".to_string(),
157 }],
158 "foobar@example.net",
159 "example.net",
160 );
161
162 assert_eq!(
163 v,
164 vec![ServerParams {
165 protocol: Protocol::Imap,
166 hostname: "example.net".to_string(),
167 port: 993,
168 socket: Socket::Ssl,
169 username: "foobar".to_string(),
170 }],
171 );
172
173 let v = expand_param_vector(
174 vec![ServerParams {
175 protocol: Protocol::Smtp,
176 hostname: "example.net".to_string(),
177 port: 123,
178 socket: Socket::Automatic,
179 username: "foobar".to_string(),
180 }],
181 "foobar@example.net",
182 "example.net",
183 );
184
185 assert_eq!(
186 v,
187 vec![
188 ServerParams {
189 protocol: Protocol::Smtp,
190 hostname: "example.net".to_string(),
191 port: 123,
192 socket: Socket::Ssl,
193 username: "foobar".to_string(),
194 },
195 ServerParams {
196 protocol: Protocol::Smtp,
197 hostname: "example.net".to_string(),
198 port: 123,
199 socket: Socket::Starttls,
200 username: "foobar".to_string(),
201 },
202 ],
203 );
204
205 let v = expand_param_vector(
206 vec![ServerParams {
207 protocol: Protocol::Smtp,
208 hostname: "example.net".to_string(),
209 port: 123,
210 socket: Socket::Plain,
211 username: "foobar".to_string(),
212 }],
213 "foobar@example.net",
214 "example.net",
215 );
216 assert_eq!(
217 v,
218 vec![ServerParams {
219 protocol: Protocol::Smtp,
220 hostname: "example.net".to_string(),
221 port: 123,
222 socket: Socket::Plain,
223 username: "foobar".to_string(),
224 }],
225 );
226
227 let v = expand_param_vector(
229 vec![ServerParams {
230 protocol: Protocol::Imap,
231 hostname: "".to_string(),
232 port: 10480,
233 socket: Socket::Ssl,
234 username: "foobar".to_string(),
235 }],
236 "foobar@example.net",
237 "example.net",
238 );
239 assert_eq!(
240 v,
241 vec![
242 ServerParams {
243 protocol: Protocol::Imap,
244 hostname: "imap.example.net".to_string(),
245 port: 10480,
246 socket: Socket::Ssl,
247 username: "foobar".to_string(),
248 },
249 ServerParams {
250 protocol: Protocol::Imap,
251 hostname: "mail.example.net".to_string(),
252 port: 10480,
253 socket: Socket::Ssl,
254 username: "foobar".to_string(),
255 },
256 ServerParams {
257 protocol: Protocol::Imap,
258 hostname: "example.net".to_string(),
259 port: 10480,
260 socket: Socket::Ssl,
261 username: "foobar".to_string(),
262 }
263 ],
264 );
265
266 let v = expand_param_vector(
269 vec![ServerParams {
270 protocol: Protocol::Smtp,
271 hostname: "example.net".to_string(),
272 port: 0,
273 socket: Socket::Automatic,
274 username: "foobar".to_string(),
275 }],
276 "foobar@example.net",
277 "example.net",
278 );
279 assert_eq!(
280 v,
281 vec![
282 ServerParams {
283 protocol: Protocol::Smtp,
284 hostname: "example.net".to_string(),
285 port: 465,
286 socket: Socket::Ssl,
287 username: "foobar".to_string(),
288 },
289 ServerParams {
290 protocol: Protocol::Smtp,
291 hostname: "example.net".to_string(),
292 port: 587,
293 socket: Socket::Starttls,
294 username: "foobar".to_string(),
295 },
296 ],
297 );
298
299 let v = expand_param_vector(
308 vec![ServerParams {
309 protocol: Protocol::Imap,
310 hostname: "example.net".to_string(),
311 port: 0,
312 socket: Socket::Automatic,
313 username: "".to_string(),
314 }],
315 "foobar@example.net",
316 "example.net",
317 );
318 assert_eq!(
319 v,
320 vec![
321 ServerParams {
322 protocol: Protocol::Imap,
323 hostname: "example.net".to_string(),
324 port: 993,
325 socket: Socket::Ssl,
326 username: "foobar@example.net".to_string(),
327 },
328 ServerParams {
329 protocol: Protocol::Imap,
330 hostname: "example.net".to_string(),
331 port: 143,
332 socket: Socket::Starttls,
333 username: "foobar@example.net".to_string(),
334 },
335 ],
336 );
337 }
338}