Mercurial > crates > systemd-socket
view src/resolv_addr.rs @ 26:0feab4f4c2ce
Relax version requirements and update MSRV
The MSRV was accidentally increased without documentation. Increase
itself is fine since it satisfies "latest stable Debian" condition but
given there are soundness issues this relaxes the version requirements
to work on 1.48 and also documents it.
| author | Martin Habovstiak <martin.habovstiak@gmail.com> |
|---|---|
| date | Fri, 28 Feb 2025 23:10:11 +0100 |
| parents | 66c0e10c89fc |
| children | cfef4593e207 |
line wrap: on
line source
use thiserror::Error; use std::fmt; #[derive(Debug, PartialEq)] pub(crate) struct ResolvAddr(String); impl ResolvAddr { pub(crate) fn as_str(&self) -> &str { &self.0 } pub(crate) fn try_from_generic<T: std::ops::Deref<Target=str> + Into<String>>(string: T) -> Result<Self, ResolvAddrError> { // can't use a combinator due to borrowing let colon = match string.rfind(':') { Some(colon) => colon, None => return Err(ResolvAddrError::MissingPort(string.into())), }; let (hostname, port) = string.split_at(colon); if let Err(error) = port[1..].parse::<u16>() { return Err(ResolvAddrError::InvalidPort { string: string.into(), error, }); } let len = hostname.len(); if len > 253 { return Err(ResolvAddrError::TooLong { string: string.into(), len, } ) } let mut label_start = 0usize; for (i, c) in hostname.chars().enumerate() { match c { '.' => { if i - label_start == 0 { return Err(ResolvAddrError::EmptyLabel { string: string.into(), label_start, }); } label_start = i + 1; }, 'a'..='z' | 'A'..='Z' | '0'..='9' | '-' => (), _ => return Err(ResolvAddrError::InvalidCharacter { string: string.into(), c, pos: i, }), } if i - label_start > 63 { return Err(ResolvAddrError::LongLabel { string: string.into(), label_start, label_end: i, }); } } Ok(ResolvAddr(string.into())) } } impl fmt::Display for ResolvAddr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } #[derive(Debug, Error)] pub(crate) enum ResolvAddrError { #[error("hostname {string} has {len} character which exceeds the limit of 253")] TooLong { string: String, len: usize }, #[error("invalid character {c} in hostname {string} at position {pos}")] InvalidCharacter { string: String, pos: usize, c: char, }, #[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)] LongLabel { string: String, label_start: usize, label_end: usize, }, #[error("hostname {string} contains an empty label at position {label_start}")] EmptyLabel { string: String, label_start: usize, }, #[error("the address {0} is missing a port")] MissingPort(String), #[error("failed to parse port numer in the address {string}")] InvalidPort { string: String, error: std::num::ParseIntError, }, }
