use std::{ net::{ IpAddr, AddrParseError, }, str, error, fmt, }; #[derive(Debug)] pub struct XFormatError; impl error::Error for XFormatError{} impl fmt::Display for XFormatError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "X-Forwarded-For was not in the correct format") } } #[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Default)] pub struct XForwardedFor(Vec); impl XForwardedFor { pub fn new() -> Self { Self(Vec::new()) } pub fn single(ip: impl Into) -> Self { Self(vec![ip.into()]) } pub fn addrs(&self) -> &[IpAddr] { &self.0[..] } pub fn into_first(self) -> Option { self.0.into_iter().next() } pub fn into_addrs(self) -> Vec { self.0 } } impl str::FromStr for XForwardedFor { type Err = XFormatError; fn from_str(s: &str) -> Result { let mut output = Vec::new(); for next in s.split(',') { output.push(next.trim().parse()?) } Ok(Self(output)) } } impl From for XFormatError { #[inline(always)] fn from(_: AddrParseError) -> Self { Self } }