jiff/error/fmt/
temporal.rs

1use crate::{error, tz::Offset, util::escape};
2
3#[derive(Clone, Debug)]
4pub(crate) enum Error {
5    #[cfg(not(feature = "alloc"))]
6    AllocPosixTimeZone,
7    AmbiguousTimeMonthDay,
8    AmbiguousTimeYearMonth,
9    CivilDateTimeZulu,
10    ConvertDateTimeToTimestamp {
11        offset: Offset,
12    },
13    EmptyTimeZone,
14    ExpectedDateDesignatorFoundByte {
15        byte: u8,
16    },
17    ExpectedDateDesignatorFoundEndOfInput,
18    ExpectedDurationDesignatorFoundByte {
19        byte: u8,
20    },
21    ExpectedDurationDesignatorFoundEndOfInput,
22    ExpectedFourDigitYear,
23    ExpectedNoSeparator,
24    ExpectedOneDigitWeekday,
25    ExpectedSeparatorFoundByte {
26        byte: u8,
27    },
28    ExpectedSeparatorFoundEndOfInput,
29    ExpectedSixDigitYear,
30    ExpectedTimeDesignator,
31    ExpectedTimeDesignatorFoundByte {
32        byte: u8,
33    },
34    ExpectedTimeDesignatorFoundEndOfInput,
35    ExpectedTimeUnits,
36    ExpectedTwoDigitDay,
37    ExpectedTwoDigitHour,
38    ExpectedTwoDigitMinute,
39    ExpectedTwoDigitMonth,
40    ExpectedTwoDigitSecond,
41    ExpectedTwoDigitWeekNumber,
42    ExpectedWeekPrefixFoundByte {
43        byte: u8,
44    },
45    ExpectedWeekPrefixFoundEndOfInput,
46    FailedDayInDate,
47    FailedDayInMonthDay,
48    FailedFractionalSecondInTime,
49    FailedHourInTime,
50    FailedMinuteInTime,
51    FailedMonthInDate,
52    FailedMonthInMonthDay,
53    FailedMonthInYearMonth,
54    FailedOffsetNumeric,
55    FailedSecondInTime,
56    FailedSeparatorAfterMonth,
57    FailedSeparatorAfterWeekNumber,
58    FailedSeparatorAfterYear,
59    FailedTzdbLookup,
60    FailedWeekNumberInDate,
61    FailedWeekNumberPrefixInDate,
62    FailedWeekdayInDate,
63    FailedYearInDate,
64    FailedYearInYearMonth,
65    InvalidDate,
66    InvalidMonthDay,
67    InvalidTimeZoneUtf8,
68    InvalidWeekDate,
69    InvalidYearMonth,
70    InvalidYearZero,
71    MissingOffsetInTimestamp,
72    MissingTimeInDate,
73    MissingTimeInTimestamp,
74    MissingTimeZoneAnnotation,
75    ParseDayTwoDigit,
76    ParseHourTwoDigit,
77    ParseMinuteTwoDigit,
78    ParseMonthTwoDigit,
79    ParseSecondTwoDigit,
80    ParseWeekNumberTwoDigit,
81    ParseWeekdayOneDigit,
82    ParseYearFourDigit,
83    ParseYearSixDigit,
84    // This is the only error for formatting a Temporal value. And
85    // actually, it's not even part of Temporal, but just lives in that
86    // module (for convenience reasons).
87    PrintTimeZoneFailure,
88}
89
90impl error::IntoError for Error {
91    fn into_error(self) -> error::Error {
92        self.into()
93    }
94}
95
96impl From<Error> for error::Error {
97    #[cold]
98    #[inline(never)]
99    fn from(err: Error) -> error::Error {
100        error::ErrorKind::FmtTemporal(err).into()
101    }
102}
103
104impl core::fmt::Display for Error {
105    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
106        use self::Error::*;
107
108        match *self {
109            #[cfg(not(feature = "alloc"))]
110            AllocPosixTimeZone => f.write_str(
111                "cannot parsed time zones other than IANA time zone \
112                 identifiers or fixed offsets \
113                 without the `alloc` crate feature enabled for `jiff`",
114            ),
115            AmbiguousTimeMonthDay => {
116                f.write_str("parsed time is ambiguous with a month-day date")
117            }
118            AmbiguousTimeYearMonth => {
119                f.write_str("parsed time is ambiguous with a year-month date")
120            }
121            CivilDateTimeZulu => f.write_str(
122                "cannot parse civil date/time from string with a Zulu \
123                 offset, parse as a `jiff::Timestamp` first \
124                 and convert to a civil date/time instead",
125            ),
126            ConvertDateTimeToTimestamp { offset } => write!(
127                f,
128                "failed to convert civil datetime to timestamp \
129                 with offset {offset}",
130            ),
131            EmptyTimeZone => {
132                f.write_str("an empty string is not a valid time zone")
133            }
134            ExpectedDateDesignatorFoundByte { byte } => write!(
135                f,
136                "expected to find date unit designator suffix \
137                 (`Y`, `M`, `W` or `D`), but found `{byte}` instead",
138                byte = escape::Byte(byte),
139            ),
140            ExpectedDateDesignatorFoundEndOfInput => f.write_str(
141                "expected to find date unit designator suffix \
142                 (`Y`, `M`, `W` or `D`), but found end of input",
143            ),
144            ExpectedDurationDesignatorFoundByte { byte } => write!(
145                f,
146                "expected to find duration beginning with `P` or `p`, \
147                 but found `{byte}` instead",
148                byte = escape::Byte(byte),
149            ),
150            ExpectedDurationDesignatorFoundEndOfInput => f.write_str(
151                "expected to find duration beginning with `P` or `p`, \
152                 but found end of input",
153            ),
154            ExpectedFourDigitYear => f.write_str(
155                "expected four digit year (or leading sign for \
156                 six digit year), but found end of input",
157            ),
158            ExpectedNoSeparator => f.write_str(
159                "expected no separator since none was \
160                 found after the year, but found a `-` separator",
161            ),
162            ExpectedOneDigitWeekday => f.write_str(
163                "expected one digit weekday, but found end of input",
164            ),
165            ExpectedSeparatorFoundByte { byte } => write!(
166                f,
167                "expected `-` separator, but found `{byte}`",
168                byte = escape::Byte(byte),
169            ),
170            ExpectedSeparatorFoundEndOfInput => {
171                f.write_str("expected `-` separator, but found end of input")
172            }
173            ExpectedSixDigitYear => f.write_str(
174                "expected six digit year (because of a leading sign), \
175                 but found end of input",
176            ),
177            ExpectedTimeDesignator => f.write_str(
178                "parsing ISO 8601 duration in this context requires \
179                 that the duration contain a time component and no \
180                 components of days or greater",
181            ),
182            ExpectedTimeDesignatorFoundByte { byte } => write!(
183                f,
184                "expected to find time unit designator suffix \
185                 (`H`, `M` or `S`), but found `{byte}` instead",
186                byte = escape::Byte(byte),
187            ),
188            ExpectedTimeDesignatorFoundEndOfInput => f.write_str(
189                "expected to find time unit designator suffix \
190                 (`H`, `M` or `S`), but found end of input",
191            ),
192            ExpectedTimeUnits => f.write_str(
193                "found a time designator (`T` or `t`) in an ISO 8601 \
194                 duration string, but did not find any time units",
195            ),
196            ExpectedTwoDigitDay => {
197                f.write_str("expected two digit day, but found end of input")
198            }
199            ExpectedTwoDigitHour => {
200                f.write_str("expected two digit hour, but found end of input")
201            }
202            ExpectedTwoDigitMinute => f.write_str(
203                "expected two digit minute, but found end of input",
204            ),
205            ExpectedTwoDigitMonth => {
206                f.write_str("expected two digit month, but found end of input")
207            }
208            ExpectedTwoDigitSecond => f.write_str(
209                "expected two digit second, but found end of input",
210            ),
211            ExpectedTwoDigitWeekNumber => f.write_str(
212                "expected two digit week number, but found end of input",
213            ),
214            ExpectedWeekPrefixFoundByte { byte } => write!(
215                f,
216                "expected `W` or `w`, but found `{byte}` instead",
217                byte = escape::Byte(byte),
218            ),
219            ExpectedWeekPrefixFoundEndOfInput => {
220                f.write_str("expected `W` or `w`, but found end of input")
221            }
222            FailedDayInDate => f.write_str("failed to parse day in date"),
223            FailedDayInMonthDay => {
224                f.write_str("failed to payse day in month-day")
225            }
226            FailedFractionalSecondInTime => {
227                f.write_str("failed to parse fractional seconds in time")
228            }
229            FailedHourInTime => f.write_str("failed to parse hour in time"),
230            FailedMinuteInTime => {
231                f.write_str("failed to parse minute in time")
232            }
233            FailedMonthInDate => f.write_str("failed to parse month in date"),
234            FailedMonthInMonthDay => {
235                f.write_str("failed to parse month in month-day")
236            }
237            FailedMonthInYearMonth => {
238                f.write_str("failed to parse month in year-month")
239            }
240            FailedOffsetNumeric => f.write_str(
241                "offset successfully parsed, \
242                 but failed to convert to numeric `jiff::tz::Offset`",
243            ),
244            FailedSecondInTime => {
245                f.write_str("failed to parse second in time")
246            }
247            FailedSeparatorAfterMonth => {
248                f.write_str("failed to parse separator after month")
249            }
250            FailedSeparatorAfterWeekNumber => {
251                f.write_str("failed to parse separator after week number")
252            }
253            FailedSeparatorAfterYear => {
254                f.write_str("failed to parse separator after year")
255            }
256            FailedTzdbLookup => f.write_str(
257                "parsed apparent IANA time zone identifier, \
258                 but the tzdb lookup failed",
259            ),
260            FailedWeekNumberInDate => {
261                f.write_str("failed to parse week number in date")
262            }
263            FailedWeekNumberPrefixInDate => {
264                f.write_str("failed to parse week number prefix in date")
265            }
266            FailedWeekdayInDate => {
267                f.write_str("failed to parse weekday in date")
268            }
269            FailedYearInDate => f.write_str("failed to parse year in date"),
270            FailedYearInYearMonth => {
271                f.write_str("failed to parse year in year-month")
272            }
273            InvalidDate => f.write_str("parsed date is not valid"),
274            InvalidMonthDay => f.write_str("parsed month-day is not valid"),
275            InvalidTimeZoneUtf8 => f.write_str(
276                "found plausible IANA time zone identifier, \
277                 but it is not valid UTF-8",
278            ),
279            InvalidWeekDate => f.write_str("parsed week date is not valid"),
280            InvalidYearMonth => f.write_str("parsed year-month is not valid"),
281            InvalidYearZero => f.write_str(
282                "year zero must be written without a sign or a \
283                 positive sign, but not a negative sign",
284            ),
285            MissingOffsetInTimestamp => f.write_str(
286                "failed to find offset component, \
287                 which is required for parsing a timestamp",
288            ),
289            MissingTimeInDate => f.write_str(
290                "successfully parsed date, but no time component was found",
291            ),
292            MissingTimeInTimestamp => f.write_str(
293                "failed to find time component, \
294                 which is required for parsing a timestamp",
295            ),
296            MissingTimeZoneAnnotation => f.write_str(
297                "failed to find time zone annotation in square brackets, \
298                 which is required for parsing a zoned datetime",
299            ),
300            ParseDayTwoDigit => {
301                f.write_str("failed to parse two digit integer as day")
302            }
303            ParseHourTwoDigit => {
304                f.write_str("failed to parse two digit integer as hour")
305            }
306            ParseMinuteTwoDigit => {
307                f.write_str("failed to parse two digit integer as minute")
308            }
309            ParseMonthTwoDigit => {
310                f.write_str("failed to parse two digit integer as month")
311            }
312            ParseSecondTwoDigit => {
313                f.write_str("failed to parse two digit integer as second")
314            }
315            ParseWeekNumberTwoDigit => {
316                f.write_str("failed to parse two digit integer as week number")
317            }
318            ParseWeekdayOneDigit => {
319                f.write_str("failed to parse one digit integer as weekday")
320            }
321            ParseYearFourDigit => {
322                f.write_str("failed to parse four digit integer as year")
323            }
324            ParseYearSixDigit => {
325                f.write_str("failed to parse six digit integer as year")
326            }
327            PrintTimeZoneFailure => f.write_str(
328                "time zones without IANA identifiers that aren't either \
329                 fixed offsets or a POSIX time zone can't be serialized \
330                 (this typically occurs when this is a system time zone \
331                  derived from `/etc/localtime` on Unix systems that \
332                  isn't symlinked to an entry in `/usr/share/zoneinfo`)",
333            ),
334        }
335    }
336}