Skip to main content

jiff/error/fmt/
rfc2822.rs

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}