1#[cfg(not(test))]
2pub(crate) use self::disabled::*;
3#[cfg(test)]
4pub(crate) use self::enabled::*;
5
6#[cfg(not(test))]
7mod disabled {
8 #[derive(Clone, Debug)]
9 pub(crate) enum Error {}
10
11 impl core::fmt::Display for Error {
12 fn fmt(&self, _: &mut core::fmt::Formatter) -> core::fmt::Result {
13 unreachable!()
14 }
15 }
16}
17
18#[cfg(test)]
19mod enabled {
20 use alloc::boxed::Box;
21
22 use crate::error;
23
24 pub(crate) const MAX_LINE_LEN: usize = 2047;
30
31 #[derive(Clone, Debug)]
32 pub(crate) enum Error {
33 DuplicateLink { name: Box<str> },
34 DuplicateLinkZone { name: Box<str> },
35 DuplicateZone { name: Box<str> },
36 DuplicateZoneLink { name: Box<str> },
37 ExpectedCloseQuote,
38 ExpectedColonAfterHour,
39 ExpectedColonAfterMinute,
40 ExpectedContinuationZoneThreeFields,
41 ExpectedContinuationZoneLine { name: Box<str> },
42 ExpectedDotAfterSeconds,
43 ExpectedFirstZoneFourFields,
44 ExpectedLinkTwoFields,
45 ExpectedMinuteAfterHours,
46 ExpectedNameBegin,
47 ExpectedNanosecondDigits,
48 ExpectedNonEmptyAbbreviation,
49 ExpectedNonEmptyAt,
50 ExpectedNonEmptyName,
51 ExpectedNonEmptySave,
52 ExpectedNonEmptyZoneName,
53 ExpectedNothingAfterTime,
54 ExpectedRuleNineFields { got: usize },
55 ExpectedSecondAfterMinutes,
56 ExpectedTimeOneHour,
57 ExpectedUntilYear,
58 ExpectedWhitespaceAfterQuotedField,
59 ExpectedZoneNameComponentNoDots { component: Box<str> },
60 FailedContinuationZone,
61 FailedLinkLine,
62 FailedParseDay,
63 FailedParseFieldAt,
64 FailedParseFieldFormat,
65 FailedParseFieldFrom,
66 FailedParseFieldIn,
67 FailedParseFieldLetters,
68 FailedParseFieldLinkName,
69 FailedParseFieldLinkTarget,
70 FailedParseFieldName,
71 FailedParseFieldOn,
72 FailedParseFieldRules,
73 FailedParseFieldSave,
74 FailedParseFieldStdOff,
75 FailedParseFieldTo,
76 FailedParseFieldUntil,
77 FailedParseHour,
78 FailedParseMinute,
79 FailedParseMonth,
80 FailedParseNanosecond,
81 FailedParseSecond,
82 FailedParseTimeDuration,
83 FailedParseYear,
84 FailedRule { name: Box<str> },
85 FailedRuleLine,
86 FailedZoneFirst,
87 Line { number: usize },
88 LineMaxLength,
89 LineNul,
90 LineOverflow,
91 InvalidAbbreviation,
92 InvalidRuleYear { start: i16, end: i16 },
93 InvalidUtf8,
94 UnrecognizedAtTimeSuffix,
95 UnrecognizedDayOfMonthFormat,
96 UnrecognizedDayOfWeek,
97 UnrecognizedMonthName,
98 UnrecognizedSaveTimeSuffix,
99 UnrecognizedTrailingTimeDuration,
100 UnrecognizedZicLine,
101 }
102
103 impl From<Error> for error::Error {
104 #[cold]
105 #[inline(never)]
106 fn from(err: Error) -> error::Error {
107 error::ErrorKind::TzZic(err).into()
108 }
109 }
110
111 impl error::IntoError for Error {
112 fn into_error(self) -> error::Error {
113 self.into()
114 }
115 }
116
117 impl core::fmt::Display for Error {
118 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
119 use self::Error::*;
120
121 match *self {
122 DuplicateLink { ref name } => {
123 write!(f, "found duplicate link with name `{name}`")
124 }
125 DuplicateLinkZone { ref name } => write!(
126 f,
127 "found link with name `{name}` that conflicts \
128 with a zone of the same name",
129 ),
130 DuplicateZone { ref name } => {
131 write!(f, "found duplicate zone with name `{name}`")
132 }
133 DuplicateZoneLink { ref name } => write!(
134 f,
135 "found zone with name `{name}` that conflicts \
136 with a link of the same name",
137 ),
138 ExpectedCloseQuote => {
139 f.write_str("found unclosed quote for field")
140 }
141 ExpectedColonAfterHour => {
142 f.write_str("expected `:` after hours")
143 }
144 ExpectedColonAfterMinute => {
145 f.write_str("expected `:` after minutes")
146 }
147 ExpectedContinuationZoneLine { ref name } => write!(
148 f,
149 "expected continuation zone line for `{name}`, \
150 but found end of data instead",
151 ),
152 ExpectedContinuationZoneThreeFields => f.write_str(
153 "expected continuation `ZONE` line \
154 to have at least 3 fields",
155 ),
156 ExpectedDotAfterSeconds => {
157 f.write_str("expected `.` after seconds")
158 }
159 ExpectedFirstZoneFourFields => f.write_str(
160 "expected first `ZONE` line to have at least 4 fields",
161 ),
162 ExpectedLinkTwoFields => {
163 f.write_str("expected exactly 2 fields after `LINK`")
164 }
165 ExpectedMinuteAfterHours => {
166 f.write_str("expected minute digits after `HH:`")
167 }
168 ExpectedNameBegin => f.write_str(
169 "`NAME` field cannot begin with a digit, `+` or `-`, \
170 but found `NAME` that begins with one of those",
171 ),
172 ExpectedNanosecondDigits => {
173 f.write_str("expected nanosecond digits after `HH:MM:SS.`")
174 }
175 ExpectedNonEmptyAbbreviation => f.write_str(
176 "empty time zone abbreviations are not allowed",
177 ),
178 ExpectedNonEmptyAt => {
179 f.write_str("`AT` field for rule cannot be empty")
180 }
181 ExpectedNonEmptyName => {
182 f.write_str("`NAME` field for rule cannot be empty")
183 }
184 ExpectedNonEmptySave => {
185 f.write_str("`SAVE` field for rule cannot be empty")
186 }
187 ExpectedNonEmptyZoneName => {
188 f.write_str("zone names cannot be empty")
189 }
190 ExpectedNothingAfterTime => f.write_str(
191 "expected no more fields after time of day, \
192 but found at least one",
193 ),
194 ExpectedRuleNineFields { got } => write!(
195 f,
196 "expected exactly 9 fields for rule, \
197 but found {got} fields",
198 ),
199 ExpectedSecondAfterMinutes => {
200 f.write_str("expected second digits after `HH:MM:`")
201 }
202 ExpectedTimeOneHour => f.write_str(
203 "expected time duration to contain \
204 at least one hour digit",
205 ),
206 ExpectedUntilYear => f.write_str("expected at least a year"),
207 ExpectedWhitespaceAfterQuotedField => {
208 f.write_str("expected whitespace after quoted field")
209 }
210 ExpectedZoneNameComponentNoDots { ref component } => write!(
211 f,
212 "component `{component}` in zone name cannot \
213 be \".\" or \"..\"",
214 ),
215 FailedContinuationZone => {
216 f.write_str("failed to parse continuation `Zone` line")
217 }
218 FailedLinkLine => f.write_str("failed to parse `Link` line"),
219 FailedParseDay => f.write_str("failed to parse day"),
220 FailedParseFieldAt => {
221 f.write_str("failed to parse `NAME` field")
222 }
223 FailedParseFieldFormat => {
224 f.write_str("failed to parse `FORMAT` field")
225 }
226 FailedParseFieldFrom => {
227 f.write_str("failed to parse `FROM` field")
228 }
229 FailedParseFieldIn => {
230 f.write_str("failed to parse `IN` field")
231 }
232 FailedParseFieldLetters => {
233 f.write_str("failed to parse `LETTERS` field")
234 }
235 FailedParseFieldLinkName => {
236 f.write_str("failed to parse `LINK` name field")
237 }
238 FailedParseFieldLinkTarget => {
239 f.write_str("failed to parse `LINK` target field")
240 }
241 FailedParseFieldName => {
242 f.write_str("failed to parse `NAME` field")
243 }
244 FailedParseFieldOn => {
245 f.write_str("failed to parse `ON` field")
246 }
247 FailedParseFieldRules => {
248 f.write_str("failed to parse `RULES` field")
249 }
250 FailedParseFieldSave => {
251 f.write_str("failed to parse `SAVE` field")
252 }
253 FailedParseFieldStdOff => {
254 f.write_str("failed to parse `STDOFF` field")
255 }
256 FailedParseFieldTo => {
257 f.write_str("failed to parse `TO` field")
258 }
259 FailedParseFieldUntil => {
260 f.write_str("failed to parse `UNTIL` field")
261 }
262 FailedParseHour => f.write_str("failed to parse hour"),
263 FailedParseMinute => f.write_str("failed to parse minute"),
264 FailedParseMonth => f.write_str("failed to parse month"),
265 FailedParseNanosecond => {
266 f.write_str("failed to parse nanosecond")
267 }
268 FailedParseSecond => f.write_str("failed to parse second"),
269 FailedParseTimeDuration => {
270 f.write_str("failed to parse time duration")
271 }
272 FailedParseYear => f.write_str("failed to parse year"),
273 FailedRule { name: ref rule } => {
274 write!(f, "failed to parse rule `{rule}`")
275 }
276 FailedRuleLine => f.write_str("failed to parse `Rule` line"),
277 FailedZoneFirst => {
278 f.write_str("failed to parse first `Zone` line")
279 }
280 InvalidAbbreviation => f.write_str(
281 "time zone abbreviation \
282 contains invalid character; only \"+\", \"-\" and \
283 ASCII alpha-numeric characters are allowed",
284 ),
285 InvalidRuleYear { start, end } => write!(
286 f,
287 "found start year={start} \
288 to be greater than end year={end}"
289 ),
290 InvalidUtf8 => f.write_str("invalid UTF-8"),
291 Line { number } => write!(f, "line {number}"),
292 LineMaxLength => write!(
293 f,
294 "found line with length that exceeds \
295 max length of {MAX_LINE_LEN}",
296 ),
297 LineNul => f.write_str(
298 "found line with NUL byte, which isn't allowed",
299 ),
300 LineOverflow => f.write_str("line count overflowed"),
301 UnrecognizedAtTimeSuffix => {
302 f.write_str("unrecognized `AT` time suffix")
303 }
304 UnrecognizedDayOfMonthFormat => {
305 f.write_str("unrecognized format for day-of-month")
306 }
307 UnrecognizedDayOfWeek => {
308 f.write_str("unrecognized day of the week")
309 }
310 UnrecognizedMonthName => {
311 f.write_str("unrecognized month name")
312 }
313 UnrecognizedSaveTimeSuffix => {
314 f.write_str("unrecognized `SAVE` time suffix")
315 }
316 UnrecognizedTrailingTimeDuration => {
317 f.write_str("found unrecognized suffix in time duration")
318 }
319 UnrecognizedZicLine => f.write_str("unrecognized zic line"),
320 }
321 }
322 }
323}