Skip to main content

addr/
error.rs

1//! The errors returned by this crate
2
3use core::fmt;
4
5pub(crate) type Result<T> = core::result::Result<T, Kind>;
6
7/// Information about the error and its input
8#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
9pub struct Error<'a> {
10    kind: Kind,
11    input: &'a str,
12}
13
14impl<'a> Error<'a> {
15    /// The kind of error this is
16    pub const fn kind(&self) -> Kind {
17        self.kind
18    }
19
20    /// The input that resulted in this error
21    pub const fn input(&self) -> &'a str {
22        self.input
23    }
24}
25
26impl<'a> fmt::Display for Error<'a> {
27    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28        match self.kind {
29            Kind::NameTooLong => write!(f, "'{}' is too long", self.input),
30            Kind::NetDisabled => write!(f, "'{}'; can't parse email addresses containing IP addresses when `net` feature is disabled", self.input),
31            Kind::EmptyLabel => write!(f, "'{}' contains an empty label", self.input),
32            Kind::EmailLocalTooLong => {
33                write!(f, "the user local part in '{}' is too long", self.input)
34            }
35            Kind::EmailTooLong => write!(f, "'{}' is too long for an email address", self.input),
36            Kind::EmptyName => write!(f, "name is empty"),
37            Kind::IllegalCharacter => write!(f, "'{}' contains an illegal character", self.input),
38            Kind::InvalidDomain => write!(f, "'{}' is not a valid domain name", self.input),
39            Kind::InvalidIpAddr => write!(f, "'{}' contains an invalid IP address", self.input),
40            Kind::LabelEndNotAlnum => {
41                write!(
42                    f,
43                    "'{}' has a label that does not end with an alphanumeric character",
44                    self.input
45                )
46            }
47            Kind::LabelStartNotAlnum => {
48                write!(
49                    f,
50                    "'{}' has a label that does not start with an alphanumeric character",
51                    self.input
52                )
53            }
54            Kind::LabelTooLong => write!(f, "'{}' has a label that is too long", self.input),
55            Kind::NoAtSign => write!(f, "'{}' does not have an @ sign", self.input),
56            Kind::NoHostPart => write!(f, "'{}' does not have a host part", self.input),
57            Kind::NoUserPart => write!(f, "'{}' does not have a user local part", self.input),
58            Kind::NumericTld => write!(f, "'{}' has a numeric TLD", self.input),
59            Kind::QuoteUnclosed => write!(f, "'{}' has an unclosed quotation mark", self.input),
60            Kind::TooManyLabels => write!(f, "'{}' contains too many labels", self.input),
61        }
62    }
63}
64
65#[cfg(feature = "std")]
66impl<'a> std::error::Error for Error<'a> {}
67
68/// Description of the error
69#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
70#[non_exhaustive]
71pub enum Kind {
72    NameTooLong,
73    NetDisabled,
74    EmptyLabel,
75    EmailLocalTooLong,
76    EmailTooLong,
77    EmptyName,
78    IllegalCharacter,
79    InvalidDomain,
80    InvalidIpAddr,
81    LabelEndNotAlnum,
82    LabelStartNotAlnum,
83    LabelTooLong,
84    NoAtSign,
85    NoHostPart,
86    NoUserPart,
87    NumericTld,
88    QuoteUnclosed,
89    TooManyLabels,
90}
91
92impl Kind {
93    pub(crate) const fn error_with(self, input: &str) -> Error<'_> {
94        Error { kind: self, input }
95    }
96}
97
98#[cfg(feature = "std")]
99impl From<std::net::AddrParseError> for Kind {
100    fn from(_: std::net::AddrParseError) -> Self {
101        Self::InvalidIpAddr
102    }
103}