Mercurial > crates > systemd-socket
comparison src/resolv_addr.rs @ 28:cfef4593e207
Run `cargo fmt`.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Sat, 19 Apr 2025 01:33:50 -0400 |
parents | 66c0e10c89fc |
children |
comparison
equal
deleted
inserted
replaced
27:85b0f4a7303d | 28:cfef4593e207 |
---|---|
1 use std::fmt; | |
1 use thiserror::Error; | 2 use thiserror::Error; |
2 use std::fmt; | |
3 | 3 |
4 #[derive(Debug, PartialEq)] | 4 #[derive(Debug, PartialEq)] |
5 pub(crate) struct ResolvAddr(String); | 5 pub(crate) struct ResolvAddr(String); |
6 | 6 |
7 impl ResolvAddr { | 7 impl ResolvAddr { |
8 pub(crate) fn as_str(&self) -> &str { | 8 pub(crate) fn as_str(&self) -> &str { |
9 &self.0 | 9 &self.0 |
10 } | 10 } |
11 | 11 |
12 pub(crate) fn try_from_generic<T: std::ops::Deref<Target=str> + Into<String>>(string: T) -> Result<Self, ResolvAddrError> { | 12 pub(crate) fn try_from_generic<T: std::ops::Deref<Target = str> + Into<String>>( |
13 string: T, | |
14 ) -> Result<Self, ResolvAddrError> { | |
13 // can't use a combinator due to borrowing | 15 // can't use a combinator due to borrowing |
14 let colon = match string.rfind(':') { | 16 let colon = match string.rfind(':') { |
15 Some(colon) => colon, | 17 Some(colon) => colon, |
16 None => return Err(ResolvAddrError::MissingPort(string.into())), | 18 None => return Err(ResolvAddrError::MissingPort(string.into())), |
17 }; | 19 }; |
18 | 20 |
19 let (hostname, port) = string.split_at(colon); | 21 let (hostname, port) = string.split_at(colon); |
20 | 22 |
21 if let Err(error) = port[1..].parse::<u16>() { | 23 if let Err(error) = port[1..].parse::<u16>() { |
22 return Err(ResolvAddrError::InvalidPort { string: string.into(), error, }); | 24 return Err(ResolvAddrError::InvalidPort { |
25 string: string.into(), | |
26 error, | |
27 }); | |
23 } | 28 } |
24 | 29 |
25 let len = hostname.len(); | 30 let len = hostname.len(); |
26 if len > 253 { | 31 if len > 253 { |
27 return Err(ResolvAddrError::TooLong { string: string.into(), len, } ) | 32 return Err(ResolvAddrError::TooLong { |
33 string: string.into(), | |
34 len, | |
35 }); | |
28 } | 36 } |
29 | 37 |
30 let mut label_start = 0usize; | 38 let mut label_start = 0usize; |
31 | 39 |
32 for (i, c) in hostname.chars().enumerate() { | 40 for (i, c) in hostname.chars().enumerate() { |
33 match c { | 41 match c { |
34 '.' => { | 42 '.' => { |
35 if i - label_start == 0 { | 43 if i - label_start == 0 { |
36 return Err(ResolvAddrError::EmptyLabel { string: string.into(), label_start, }); | 44 return Err(ResolvAddrError::EmptyLabel { |
45 string: string.into(), | |
46 label_start, | |
47 }); | |
37 } | 48 } |
38 | 49 |
39 label_start = i + 1; | 50 label_start = i + 1; |
40 }, | 51 } |
41 'a'..='z' | 'A'..='Z' | '0'..='9' | '-' => (), | 52 'a'..='z' | 'A'..='Z' | '0'..='9' | '-' => (), |
42 _ => return Err(ResolvAddrError::InvalidCharacter { string: string.into(), c, pos: i, }), | 53 _ => { |
54 return Err(ResolvAddrError::InvalidCharacter { | |
55 string: string.into(), | |
56 c, | |
57 pos: i, | |
58 }) | |
59 } | |
43 } | 60 } |
44 | 61 |
45 if i - label_start > 63 { | 62 if i - label_start > 63 { |
46 return Err(ResolvAddrError::LongLabel { string: string.into(), label_start, label_end: i, }); | 63 return Err(ResolvAddrError::LongLabel { |
64 string: string.into(), | |
65 label_start, | |
66 label_end: i, | |
67 }); | |
47 } | 68 } |
48 } | 69 } |
49 | 70 |
50 Ok(ResolvAddr(string.into())) | 71 Ok(ResolvAddr(string.into())) |
51 } | 72 } |
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 76 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
56 fmt::Display::fmt(&self.0, f) | 77 fmt::Display::fmt(&self.0, f) |
57 } | 78 } |
58 } | 79 } |
59 | 80 |
60 | |
61 #[derive(Debug, Error)] | 81 #[derive(Debug, Error)] |
62 pub(crate) enum ResolvAddrError { | 82 pub(crate) enum ResolvAddrError { |
63 #[error("hostname {string} has {len} character which exceeds the limit of 253")] | 83 #[error("hostname {string} has {len} character which exceeds the limit of 253")] |
64 TooLong { string: String, len: usize }, | 84 TooLong { string: String, len: usize }, |
65 #[error("invalid character {c} in hostname {string} at position {pos}")] | 85 #[error("invalid character {c} in hostname {string} at position {pos}")] |
66 InvalidCharacter { string: String, pos: usize, c: char, }, | 86 InvalidCharacter { string: String, pos: usize, c: char }, |
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)] | 87 #[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)] |
68 LongLabel { string: String, label_start: usize, label_end: usize, }, | 88 LongLabel { |
89 string: String, | |
90 label_start: usize, | |
91 label_end: usize, | |
92 }, | |
69 #[error("hostname {string} contains an empty label at position {label_start}")] | 93 #[error("hostname {string} contains an empty label at position {label_start}")] |
70 EmptyLabel { string: String, label_start: usize, }, | 94 EmptyLabel { string: String, label_start: usize }, |
71 #[error("the address {0} is missing a port")] | 95 #[error("the address {0} is missing a port")] |
72 MissingPort(String), | 96 MissingPort(String), |
73 #[error("failed to parse port numer in the address {string}")] | 97 #[error("failed to parse port numer in the address {string}")] |
74 InvalidPort { string: String, error: std::num::ParseIntError, }, | 98 InvalidPort { |
99 string: String, | |
100 error: std::num::ParseIntError, | |
101 }, | |
75 } | 102 } |