actix_settings/settings/
address.rs1use once_cell::sync::Lazy;
2use regex::Regex;
3use serde::Deserialize;
4
5use crate::{Error, Parse};
6
7static ADDR_REGEX: Lazy<Regex> = Lazy::new(|| {
8 Regex::new(
9 r#"(?x)
10 \[ # opening square bracket
11 (\s)* # optional whitespace
12 "(?P<host>[^"]+)" # host name (string)
13 , # separating comma
14 (\s)* # optional whitespace
15 (?P<port>\d+) # port number (integer)
16 (\s)* # optional whitespace
17 \] # closing square bracket
18 "#,
19 )
20 .expect("Failed to compile regex: ADDR_REGEX")
21});
22
23static ADDR_LIST_REGEX: Lazy<Regex> = Lazy::new(|| {
24 Regex::new(
25 r#"(?x)
26 \[ # opening square bracket (list)
27 (\s)* # optional whitespace
28 (?P<elements>(
29 \[".*", (\s)* \d+\] # element
30 (,)? # element separator
31 (\s)* # optional whitespace
32 )*)
33 (\s)* # optional whitespace
34 \] # closing square bracket (list)
35 "#,
36 )
37 .expect("Failed to compile regex: ADDRS_REGEX")
38});
39
40#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
42pub struct Address {
43 pub host: String,
45
46 pub port: u16,
48}
49
50impl Parse for Address {
51 fn parse(string: &str) -> Result<Self, Error> {
52 let mut items = string
53 .trim()
54 .trim_start_matches('[')
55 .trim_end_matches(']')
56 .split(',');
57
58 let parse_error = || Error::ParseAddressError(string.to_string());
59
60 if !ADDR_REGEX.is_match(string) {
61 return Err(parse_error());
62 }
63
64 Ok(Self {
65 host: items.next().ok_or_else(parse_error)?.trim().to_string(),
66 port: items.next().ok_or_else(parse_error)?.trim().parse()?,
67 })
68 }
69}
70
71impl Parse for Vec<Address> {
72 fn parse(string: &str) -> Result<Self, Error> {
73 let parse_error = || Error::ParseAddressError(string.to_string());
74
75 if !ADDR_LIST_REGEX.is_match(string) {
76 return Err(parse_error());
77 }
78
79 let mut addrs = vec![];
80
81 for list_caps in ADDR_LIST_REGEX.captures_iter(string) {
82 let elements = &list_caps["elements"].trim();
83 for elt_caps in ADDR_REGEX.captures_iter(elements) {
84 addrs.push(Address {
85 host: elt_caps["host"].to_string(),
86 port: elt_caps["port"].parse()?,
87 });
88 }
89 }
90
91 Ok(addrs)
92 }
93}