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 }