structured_email_address/
error.rs1use core::fmt;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Error {
8 kind: ErrorKind,
9 position: usize,
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum ErrorKind {
15 Empty,
17 MissingAtSign,
19 MultipleAtSigns,
21 EmptyLocalPart,
23 EmptyDomain,
25 LocalPartTooLong { len: usize },
27 AddressTooLong { len: usize },
29 DomainLabelTooLong { label: String, len: usize },
31 InvalidLocalPartChar { ch: char },
33 InvalidDomainChar { ch: char },
35 DomainLabelHyphen,
37 DomainNoDot,
39 UnterminatedQuotedString,
41 InvalidQuotedPair,
43 UnterminatedComment,
45 UnterminatedDomainLiteral,
47 IdnaError(String),
49 UnknownTld(String),
51 Unexpected { ch: char },
53}
54
55impl Error {
56 pub(crate) fn new(kind: ErrorKind, position: usize) -> Self {
58 Self { kind, position }
59 }
60
61 pub fn kind(&self) -> &ErrorKind {
63 &self.kind
64 }
65
66 pub fn position(&self) -> usize {
68 self.position
69 }
70}
71
72impl fmt::Display for Error {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match &self.kind {
75 ErrorKind::Empty => write!(f, "empty input"),
76 ErrorKind::MissingAtSign => write!(f, "missing '@' separator"),
77 ErrorKind::MultipleAtSigns => write!(f, "multiple unquoted '@' signs"),
78 ErrorKind::EmptyLocalPart => write!(f, "empty local part"),
79 ErrorKind::EmptyDomain => write!(f, "empty domain"),
80 ErrorKind::LocalPartTooLong { len } => {
81 write!(f, "local part too long: {len} octets (max 64)")
82 }
83 ErrorKind::AddressTooLong { len } => {
84 write!(f, "address too long: {len} octets (max 254)")
85 }
86 ErrorKind::DomainLabelTooLong { label, len } => {
87 write!(f, "domain label '{label}' too long: {len} octets (max 63)")
88 }
89 ErrorKind::InvalidLocalPartChar { ch } => {
90 write!(f, "invalid character in local part: '{ch}'")
91 }
92 ErrorKind::InvalidDomainChar { ch } => {
93 write!(f, "invalid character in domain: '{ch}'")
94 }
95 ErrorKind::DomainLabelHyphen => {
96 write!(f, "domain label starts or ends with hyphen")
97 }
98 ErrorKind::DomainNoDot => write!(f, "domain has no dot"),
99 ErrorKind::UnterminatedQuotedString => write!(f, "unterminated quoted string"),
100 ErrorKind::InvalidQuotedPair => write!(f, "invalid quoted-pair escape"),
101 ErrorKind::UnterminatedComment => write!(f, "unterminated comment"),
102 ErrorKind::UnterminatedDomainLiteral => write!(f, "unterminated domain literal"),
103 ErrorKind::IdnaError(msg) => write!(f, "IDNA error: {msg}"),
104 ErrorKind::UnknownTld(tld) => write!(f, "unknown TLD: .{tld}"),
105 ErrorKind::Unexpected { ch } => {
106 write!(
107 f,
108 "unexpected character '{ch}' at position {}",
109 self.position
110 )
111 }
112 }
113 }
114}
115
116impl std::error::Error for Error {}