1use crate::{civil::Weekday, error, util::escape};
2
3#[derive(Clone, Debug)]
4pub(crate) enum Error {
5 CommentClosingParenWithoutOpen,
6 CommentOpeningParenWithoutClose,
7 CommentTooManyNestedParens,
8 EndOfInputDay,
9 Empty,
10 EmptyAfterWhitespace,
11 EndOfInputComma,
12 EndOfInputHour,
13 EndOfInputMinute,
14 EndOfInputMonth,
15 EndOfInputOffset,
16 EndOfInputSecond,
17 EndOfInputTimeSeparator,
18 FailedTimestamp,
19 FailedZoned,
20 InconsistentWeekday { parsed: Weekday, from_date: Weekday },
21 InvalidDate,
22 InvalidMonth,
23 InvalidObsoleteOffset,
24 InvalidWeekday { got_non_digit: u8 },
25 NegativeYear,
26 ParseDay,
27 ParseHour,
28 ParseMinute,
29 ParseOffsetHour,
30 ParseOffsetMinute,
31 ParseSecond,
32 ParseYear,
33 TooShortMonth { len: u8 },
34 TooShortOffset,
35 TooShortWeekday { got_non_digit: u8, len: u8 },
36 TooShortYear { len: u8 },
37 UnexpectedByteComma { byte: u8 },
38 UnexpectedByteTimeSeparator { byte: u8 },
39 WhitespaceAfterDay,
40 WhitespaceAfterMonth,
41 WhitespaceAfterTime,
42 WhitespaceAfterTimeForObsoleteOffset,
43 WhitespaceAfterYear,
44}
45
46impl error::IntoError for Error {
47 fn into_error(self) -> error::Error {
48 self.into()
49 }
50}
51
52impl From<Error> for error::Error {
53 #[cold]
54 #[inline(never)]
55 fn from(err: Error) -> error::Error {
56 error::ErrorKind::FmtRfc2822(err).into()
57 }
58}
59
60impl core::fmt::Display for Error {
61 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
62 use self::Error::*;
63
64 match *self {
65 CommentClosingParenWithoutOpen => f.write_str(
66 "found closing parenthesis in comment with \
67 no matching opening parenthesis",
68 ),
69 CommentOpeningParenWithoutClose => f.write_str(
70 "found opening parenthesis in comment with \
71 no matching closing parenthesis",
72 ),
73 CommentTooManyNestedParens => {
74 f.write_str("found too many nested parenthesis in comment")
75 }
76 Empty => {
77 f.write_str("expected RFC 2822 datetime, but got empty string")
78 }
79 EmptyAfterWhitespace => f.write_str(
80 "expected RFC 2822 datetime, but got empty string \
81 after trimming leading whitespace",
82 ),
83 EndOfInputComma => f.write_str(
84 "expected comma after parsed weekday in \
85 RFC 2822 datetime, but found end of input instead",
86 ),
87 EndOfInputDay => {
88 f.write_str("expected numeric day, but found end of input")
89 }
90 EndOfInputHour => {
91 f.write_str("expected two digit hour, but found end of input")
92 }
93 EndOfInputMinute => f.write_str(
94 "expected two digit minute, but found end of input",
95 ),
96 EndOfInputMonth => f.write_str(
97 "expected abbreviated month name, but found end of input",
98 ),
99 EndOfInputOffset => f.write_str(
100 "expected sign for time zone offset, \
101 (or a legacy time zone name abbreviation), \
102 but found end of input",
103 ),
104 EndOfInputSecond => f.write_str(
105 "expected two digit second, but found end of input",
106 ),
107 EndOfInputTimeSeparator => f.write_str(
108 "expected time separator of `:`, but found end of input",
109 ),
110 FailedTimestamp => f.write_str(
111 "failed to parse RFC 2822 datetime into Jiff timestamp",
112 ),
113 FailedZoned => f.write_str(
114 "failed to parse RFC 2822 datetime into Jiff zoned datetime",
115 ),
116 InconsistentWeekday { parsed, from_date } => write!(
117 f,
118 "found parsed weekday of `{parsed:?}`, \
119 but parsed datetime has weekday `{from_date:?}`",
120 ),
121 InvalidDate => f.write_str("invalid date"),
122 InvalidMonth => f.write_str(
123 "expected abbreviated month name, \
124 but did not recognize a valid abbreviated month name",
125 ),
126 InvalidObsoleteOffset => f.write_str(
127 "expected obsolete RFC 2822 time zone abbreviation, \
128 but did not recognize a valid abbreviation",
129 ),
130 InvalidWeekday { got_non_digit } => write!(
131 f,
132 "expected day at beginning of RFC 2822 datetime \
133 since first non-whitespace byte, `{first}`, \
134 is not a digit, but did not recognize a valid \
135 weekday abbreviation",
136 first = escape::Byte(got_non_digit),
137 ),
138 NegativeYear => f.write_str(
139 "datetime has negative year, \
140 which cannot be formatted with RFC 2822",
141 ),
142 ParseDay => f.write_str("failed to parse day"),
143 ParseHour => f.write_str(
144 "failed to parse hour (expects a two digit integer)",
145 ),
146 ParseMinute => f.write_str(
147 "failed to parse minute (expects a two digit integer)",
148 ),
149 ParseOffsetHour => {
150 f.write_str("failed to parse hours from time zone offset")
151 }
152 ParseOffsetMinute => {
153 f.write_str("failed to parse minutes from time zone offset")
154 }
155 ParseSecond => f.write_str(
156 "failed to parse second (expects a two digit integer)",
157 ),
158 ParseYear => f.write_str(
159 "failed to parse year \
160 (expects a two, three or four digit integer)",
161 ),
162 TooShortMonth { len } => write!(
163 f,
164 "expected abbreviated month name, but remaining input \
165 is too short (remaining bytes is {len})",
166 ),
167 TooShortOffset => write!(
168 f,
169 "expected at least four digits for time zone offset \
170 after sign, but found fewer than four bytes remaining",
171 ),
172 TooShortWeekday { got_non_digit, len } => write!(
173 f,
174 "expected day at beginning of RFC 2822 datetime \
175 since first non-whitespace byte, `{first}`, \
176 is not a digit, but given string is too short \
177 (length is {len})",
178 first = escape::Byte(got_non_digit),
179 ),
180 TooShortYear { len } => write!(
181 f,
182 "expected at least two ASCII digits for parsing \
183 a year, but only found {len}",
184 ),
185 UnexpectedByteComma { byte } => write!(
186 f,
187 "expected comma after parsed weekday in \
188 RFC 2822 datetime, but found `{got}` instead",
189 got = escape::Byte(byte),
190 ),
191 UnexpectedByteTimeSeparator { byte } => write!(
192 f,
193 "expected time separator of `:`, but found `{got}`",
194 got = escape::Byte(byte),
195 ),
196 WhitespaceAfterDay => {
197 f.write_str("expected whitespace after parsing day")
198 }
199 WhitespaceAfterMonth => f.write_str(
200 "expected whitespace after parsing abbreviated month name",
201 ),
202 WhitespaceAfterTime => f.write_str(
203 "expected whitespace after parsing time: \
204 expected at least one whitespace character \
205 (space or tab), but found none",
206 ),
207 WhitespaceAfterTimeForObsoleteOffset => f.write_str(
208 "expected obsolete RFC 2822 time zone abbreviation, \
209 but found no remaining non-whitespace characters \
210 after time",
211 ),
212 WhitespaceAfterYear => {
213 f.write_str("expected whitespace after parsing year")
214 }
215 }
216 }
217}