Mercurial > crates > systemd-socket
annotate src/resolv_addr.rs @ 6:a7893294e9b2
Make the crate compilable on non-linux systems
This makes the crate compile on other operating systems. Since systemd
is only supported on Linux, it simply disables systemd features on other
systems. The API is still the same, just parsing `systemd://` string
will return an error.
| author | Martin Habovstiak <martin.habovstiak@gmail.com> |
|---|---|
| date | Fri, 27 Nov 2020 16:15:57 +0100 |
| parents | 66c0e10c89fc |
| children | cfef4593e207 |
| rev | line source |
|---|---|
|
4
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
1 use thiserror::Error; |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
2 use std::fmt; |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
3 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
4 #[derive(Debug, PartialEq)] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
5 pub(crate) struct ResolvAddr(String); |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
6 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
7 impl ResolvAddr { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
8 pub(crate) fn as_str(&self) -> &str { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
9 &self.0 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
10 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
11 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
12 pub(crate) fn try_from_generic<T: std::ops::Deref<Target=str> + Into<String>>(string: T) -> Result<Self, ResolvAddrError> { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
13 // can't use a combinator due to borrowing |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
14 let colon = match string.rfind(':') { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
15 Some(colon) => colon, |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
16 None => return Err(ResolvAddrError::MissingPort(string.into())), |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
17 }; |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
18 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
19 let (hostname, port) = string.split_at(colon); |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
20 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
21 if let Err(error) = port[1..].parse::<u16>() { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
22 return Err(ResolvAddrError::InvalidPort { string: string.into(), error, }); |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
23 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
24 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
25 let len = hostname.len(); |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
26 if len > 253 { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
27 return Err(ResolvAddrError::TooLong { string: string.into(), len, } ) |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
28 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
29 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
30 let mut label_start = 0usize; |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
31 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
32 for (i, c) in hostname.chars().enumerate() { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
33 match c { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
34 '.' => { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
35 if i - label_start == 0 { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
36 return Err(ResolvAddrError::EmptyLabel { string: string.into(), label_start, }); |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
37 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
38 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
39 label_start = i + 1; |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
40 }, |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
41 'a'..='z' | 'A'..='Z' | '0'..='9' | '-' => (), |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
42 _ => return Err(ResolvAddrError::InvalidCharacter { string: string.into(), c, pos: i, }), |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
43 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
44 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
45 if i - label_start > 63 { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
46 return Err(ResolvAddrError::LongLabel { string: string.into(), label_start, label_end: i, }); |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
47 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
48 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
49 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
50 Ok(ResolvAddr(string.into())) |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
51 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
52 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
53 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
54 impl fmt::Display for ResolvAddr { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
56 fmt::Display::fmt(&self.0, f) |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
57 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
58 } |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
59 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
60 |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
61 #[derive(Debug, Error)] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
62 pub(crate) enum ResolvAddrError { |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
63 #[error("hostname {string} has {len} character which exceeds the limit of 253")] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
64 TooLong { string: String, len: usize }, |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
65 #[error("invalid character {c} in hostname {string} at position {pos}")] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
66 InvalidCharacter { string: String, pos: usize, c: char, }, |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
67 #[error("hostname {string} contains a label {} at position {label_start} which is {} characters long - more than the limit 63", &string[(*label_start)..(*label_end)], label_end - label_start)] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
68 LongLabel { string: String, label_start: usize, label_end: usize, }, |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
69 #[error("hostname {string} contains an empty label at position {label_start}")] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
70 EmptyLabel { string: String, label_start: usize, }, |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
71 #[error("the address {0} is missing a port")] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
72 MissingPort(String), |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
73 #[error("failed to parse port numer in the address {string}")] |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
74 InvalidPort { string: String, error: std::num::ParseIntError, }, |
|
66c0e10c89fc
Support resolving hostnames
Martin Habovstiak <martin.habovstiak@gmail.com>
parents:
diff
changeset
|
75 } |
