Mercurial > crates > systemd-socket
annotate src/resolv_addr.rs @ 5:27456533853e
Attempt to setup CI using GitHub Actions
This sets up CI to test the crate on Ubuntu, Windows and macOS. It's expected to fail on Windows now and it will be fixed after we know which things need to be configured-away.
author | Martin Habovštiak <martin.habovstiak@gmail.com> |
---|---|
date | Fri, 27 Nov 2020 15:18:25 +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 } |