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