1use core::{
8 error::Error,
9 fmt,
10 num::{IntErrorKind, ParseIntError},
11};
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17#[allow(clippy::module_name_repetitions)]
18pub struct DosDateTimeRangeError(DosDateTimeRangeErrorKind);
19
20impl DosDateTimeRangeError {
21 #[inline]
22 pub(crate) const fn new(kind: DosDateTimeRangeErrorKind) -> Self {
23 Self(kind)
24 }
25
26 #[must_use]
40 #[inline]
41 pub const fn kind(&self) -> DosDateTimeRangeErrorKind {
42 self.0
43 }
44}
45
46impl fmt::Display for DosDateTimeRangeError {
47 #[inline]
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 self.kind().fmt(f)
50 }
51}
52
53impl Error for DosDateTimeRangeError {}
54
55impl From<DosDateTimeRangeErrorKind> for DosDateTimeRangeError {
56 #[inline]
57 fn from(kind: DosDateTimeRangeErrorKind) -> Self {
58 Self::new(kind)
59 }
60}
61
62#[derive(Clone, Copy, Debug, Eq, PartialEq)]
64pub enum DosDateTimeRangeErrorKind {
65 Negative,
69
70 Overflow,
76}
77
78impl fmt::Display for DosDateTimeRangeErrorKind {
79 #[inline]
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 match self {
82 Self::Negative => write!(f, "date and time is before `1980-01-01 00:00:00`"),
83 Self::Overflow => write!(f, "date and time is after `2107-12-31 23:59:58`"),
84 }
85 }
86}
87
88#[derive(Clone, Copy, Debug, Eq, PartialEq)]
91#[allow(clippy::module_name_repetitions)]
92pub struct FileTimeRangeError(FileTimeRangeErrorKind);
93
94impl FileTimeRangeError {
95 #[inline]
96 pub(crate) const fn new(kind: FileTimeRangeErrorKind) -> Self {
97 Self(kind)
98 }
99
100 #[must_use]
114 #[inline]
115 pub const fn kind(&self) -> FileTimeRangeErrorKind {
116 self.0
117 }
118}
119
120impl fmt::Display for FileTimeRangeError {
121 #[inline]
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 self.kind().fmt(f)
124 }
125}
126
127impl Error for FileTimeRangeError {}
128
129impl From<FileTimeRangeErrorKind> for FileTimeRangeError {
130 #[inline]
131 fn from(kind: FileTimeRangeErrorKind) -> Self {
132 Self::new(kind)
133 }
134}
135
136#[derive(Clone, Copy, Debug, Eq, PartialEq)]
138pub enum FileTimeRangeErrorKind {
139 Negative,
143
144 Overflow,
149}
150
151impl fmt::Display for FileTimeRangeErrorKind {
152 #[inline]
153 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 match self {
155 Self::Negative => write!(f, "date and time is before `1601-01-01 00:00:00 UTC`"),
156 Self::Overflow => write!(
157 f,
158 "date and time is after `+60056-05-28 05:36:10.955161500 UTC`"
159 ),
160 }
161 }
162}
163
164#[derive(Clone, Debug, Eq, PartialEq)]
166#[allow(clippy::module_name_repetitions)]
167pub struct ParseFileTimeError(ParseIntError);
168
169impl ParseFileTimeError {
170 #[inline]
171 pub(crate) const fn new(inner: ParseIntError) -> Self {
172 Self(inner)
173 }
174}
175
176impl fmt::Display for ParseFileTimeError {
177 #[inline]
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 let inner = &self.0;
180 if inner.kind() == &IntErrorKind::PosOverflow {
181 write!(
182 f,
183 "date and time is after `+60056-05-28 05:36:10.955161500 UTC`"
184 )
185 } else {
186 inner.fmt(f)
187 }
188 }
189}
190
191impl Error for ParseFileTimeError {
192 #[inline]
193 fn source(&self) -> Option<&(dyn Error + 'static)> {
194 Some(&self.0)
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use core::str::FromStr;
201
202 use super::*;
203
204 #[test]
205 fn clone_dos_date_time_range_error() {
206 assert_eq!(
207 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative).clone(),
208 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative)
209 );
210 assert_eq!(
211 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow).clone(),
212 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow)
213 );
214 }
215
216 #[test]
217 fn copy_dos_date_time_range_error() {
218 {
219 let a = DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative);
220 let b = a;
221 assert_eq!(a, b);
222 }
223
224 {
225 let a = DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow);
226 let b = a;
227 assert_eq!(a, b);
228 }
229 }
230
231 #[test]
232 fn debug_dos_date_time_range_error() {
233 assert_eq!(
234 format!(
235 "{:?}",
236 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative)
237 ),
238 "DosDateTimeRangeError(Negative)"
239 );
240 assert_eq!(
241 format!(
242 "{:?}",
243 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow)
244 ),
245 "DosDateTimeRangeError(Overflow)"
246 );
247 }
248
249 #[test]
250 fn dos_date_time_range_error_equality() {
251 assert_eq!(
252 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative),
253 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative)
254 );
255 assert_ne!(
256 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative),
257 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow)
258 );
259 assert_ne!(
260 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow),
261 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative)
262 );
263 assert_eq!(
264 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow),
265 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow)
266 );
267 }
268
269 #[test]
270 fn kind_dos_date_time_range_error() {
271 assert_eq!(
272 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative).kind(),
273 DosDateTimeRangeErrorKind::Negative
274 );
275 assert_eq!(
276 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow).kind(),
277 DosDateTimeRangeErrorKind::Overflow
278 );
279 }
280
281 #[test]
282 const fn kind_dos_date_time_range_error_is_const_fn() {
283 const _: DosDateTimeRangeErrorKind =
284 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative).kind();
285 }
286
287 #[test]
288 fn display_dos_date_time_range_error() {
289 assert_eq!(
290 format!(
291 "{}",
292 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative)
293 ),
294 "date and time is before `1980-01-01 00:00:00`"
295 );
296 assert_eq!(
297 format!(
298 "{}",
299 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow)
300 ),
301 "date and time is after `2107-12-31 23:59:58`"
302 );
303 }
304
305 #[test]
306 fn source_dos_date_time_range_error() {
307 assert!(
308 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative)
309 .source()
310 .is_none()
311 );
312 assert!(
313 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow)
314 .source()
315 .is_none()
316 );
317 }
318
319 #[test]
320 fn from_dos_date_time_range_error_kind_to_dos_date_time_range_error() {
321 assert_eq!(
322 DosDateTimeRangeError::from(DosDateTimeRangeErrorKind::Negative),
323 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Negative)
324 );
325 assert_eq!(
326 DosDateTimeRangeError::from(DosDateTimeRangeErrorKind::Overflow),
327 DosDateTimeRangeError::new(DosDateTimeRangeErrorKind::Overflow)
328 );
329 }
330
331 #[test]
332 fn clone_dos_date_time_range_error_kind() {
333 assert_eq!(
334 DosDateTimeRangeErrorKind::Negative.clone(),
335 DosDateTimeRangeErrorKind::Negative
336 );
337 assert_eq!(
338 DosDateTimeRangeErrorKind::Overflow.clone(),
339 DosDateTimeRangeErrorKind::Overflow
340 );
341 }
342
343 #[test]
344 fn copy_dos_date_time_range_error_kind() {
345 {
346 let a = DosDateTimeRangeErrorKind::Negative;
347 let b = a;
348 assert_eq!(a, b);
349 }
350
351 {
352 let a = DosDateTimeRangeErrorKind::Overflow;
353 let b = a;
354 assert_eq!(a, b);
355 }
356 }
357
358 #[test]
359 fn debug_dos_date_time_range_error_kind() {
360 assert_eq!(
361 format!("{:?}", DosDateTimeRangeErrorKind::Negative),
362 "Negative"
363 );
364 assert_eq!(
365 format!("{:?}", DosDateTimeRangeErrorKind::Overflow),
366 "Overflow"
367 );
368 }
369
370 #[test]
371 fn dos_date_time_range_error_kind_equality() {
372 assert_eq!(
373 DosDateTimeRangeErrorKind::Negative,
374 DosDateTimeRangeErrorKind::Negative
375 );
376 assert_ne!(
377 DosDateTimeRangeErrorKind::Negative,
378 DosDateTimeRangeErrorKind::Overflow
379 );
380 assert_ne!(
381 DosDateTimeRangeErrorKind::Overflow,
382 DosDateTimeRangeErrorKind::Negative
383 );
384 assert_eq!(
385 DosDateTimeRangeErrorKind::Overflow,
386 DosDateTimeRangeErrorKind::Overflow
387 );
388 }
389
390 #[test]
391 fn display_dos_date_time_range_error_kind() {
392 assert_eq!(
393 format!("{}", DosDateTimeRangeErrorKind::Negative),
394 "date and time is before `1980-01-01 00:00:00`"
395 );
396 assert_eq!(
397 format!("{}", DosDateTimeRangeErrorKind::Overflow),
398 "date and time is after `2107-12-31 23:59:58`"
399 );
400 }
401
402 #[test]
403 fn clone_file_time_range_error() {
404 assert_eq!(
405 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative).clone(),
406 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative)
407 );
408 assert_eq!(
409 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow).clone(),
410 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow)
411 );
412 }
413
414 #[test]
415 fn copy_file_time_range_error() {
416 {
417 let a = FileTimeRangeError::new(FileTimeRangeErrorKind::Negative);
418 let b = a;
419 assert_eq!(a, b);
420 }
421
422 {
423 let a = FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow);
424 let b = a;
425 assert_eq!(a, b);
426 }
427 }
428
429 #[test]
430 fn debug_file_time_range_error() {
431 assert_eq!(
432 format!(
433 "{:?}",
434 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative)
435 ),
436 "FileTimeRangeError(Negative)"
437 );
438 assert_eq!(
439 format!(
440 "{:?}",
441 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow)
442 ),
443 "FileTimeRangeError(Overflow)"
444 );
445 }
446
447 #[test]
448 fn file_time_range_error_equality() {
449 assert_eq!(
450 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative),
451 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative)
452 );
453 assert_ne!(
454 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative),
455 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow)
456 );
457 assert_ne!(
458 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow),
459 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative)
460 );
461 assert_eq!(
462 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow),
463 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow)
464 );
465 }
466
467 #[test]
468 fn kind_file_time_range_error() {
469 assert_eq!(
470 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative).kind(),
471 FileTimeRangeErrorKind::Negative
472 );
473 assert_eq!(
474 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow).kind(),
475 FileTimeRangeErrorKind::Overflow
476 );
477 }
478
479 #[test]
480 const fn kind_file_time_range_error_is_const_fn() {
481 const _: FileTimeRangeErrorKind =
482 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative).kind();
483 }
484
485 #[test]
486 fn display_file_time_range_error() {
487 assert_eq!(
488 format!(
489 "{}",
490 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative)
491 ),
492 "date and time is before `1601-01-01 00:00:00 UTC`"
493 );
494 assert_eq!(
495 format!(
496 "{}",
497 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow)
498 ),
499 "date and time is after `+60056-05-28 05:36:10.955161500 UTC`"
500 );
501 }
502
503 #[test]
504 fn source_file_time_range_error() {
505 assert!(
506 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative)
507 .source()
508 .is_none()
509 );
510 assert!(
511 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow)
512 .source()
513 .is_none()
514 );
515 }
516
517 #[test]
518 fn from_file_time_range_error_kind_to_file_time_range_error() {
519 assert_eq!(
520 FileTimeRangeError::from(FileTimeRangeErrorKind::Negative),
521 FileTimeRangeError::new(FileTimeRangeErrorKind::Negative)
522 );
523 assert_eq!(
524 FileTimeRangeError::from(FileTimeRangeErrorKind::Overflow),
525 FileTimeRangeError::new(FileTimeRangeErrorKind::Overflow)
526 );
527 }
528
529 #[test]
530 fn clone_file_time_range_error_kind() {
531 assert_eq!(
532 FileTimeRangeErrorKind::Negative.clone(),
533 FileTimeRangeErrorKind::Negative
534 );
535 assert_eq!(
536 FileTimeRangeErrorKind::Overflow.clone(),
537 FileTimeRangeErrorKind::Overflow
538 );
539 }
540
541 #[test]
542 fn copy_file_time_range_error_kind() {
543 {
544 let a = FileTimeRangeErrorKind::Negative;
545 let b = a;
546 assert_eq!(a, b);
547 }
548
549 {
550 let a = FileTimeRangeErrorKind::Overflow;
551 let b = a;
552 assert_eq!(a, b);
553 }
554 }
555
556 #[test]
557 fn debug_file_time_range_error_kind() {
558 assert_eq!(
559 format!("{:?}", FileTimeRangeErrorKind::Negative),
560 "Negative"
561 );
562 assert_eq!(
563 format!("{:?}", FileTimeRangeErrorKind::Overflow),
564 "Overflow"
565 );
566 }
567
568 #[test]
569 fn file_time_range_error_kind_equality() {
570 assert_eq!(
571 FileTimeRangeErrorKind::Negative,
572 FileTimeRangeErrorKind::Negative
573 );
574 assert_ne!(
575 FileTimeRangeErrorKind::Negative,
576 FileTimeRangeErrorKind::Overflow
577 );
578 assert_ne!(
579 FileTimeRangeErrorKind::Overflow,
580 FileTimeRangeErrorKind::Negative
581 );
582 assert_eq!(
583 FileTimeRangeErrorKind::Overflow,
584 FileTimeRangeErrorKind::Overflow
585 );
586 }
587
588 #[test]
589 fn display_file_time_range_error_kind() {
590 assert_eq!(
591 format!("{}", FileTimeRangeErrorKind::Negative),
592 "date and time is before `1601-01-01 00:00:00 UTC`"
593 );
594 assert_eq!(
595 format!("{}", FileTimeRangeErrorKind::Overflow),
596 "date and time is after `+60056-05-28 05:36:10.955161500 UTC`"
597 );
598 }
599
600 #[test]
601 fn debug_parse_file_time_error() {
602 assert_eq!(
603 format!(
604 "{:?}",
605 ParseFileTimeError::new(u64::from_str("").unwrap_err())
606 ),
607 "ParseFileTimeError(ParseIntError { kind: Empty })"
608 );
609 assert_eq!(
610 format!(
611 "{:?}",
612 ParseFileTimeError::new(u64::from_str("a").unwrap_err())
613 ),
614 "ParseFileTimeError(ParseIntError { kind: InvalidDigit })"
615 );
616 assert_eq!(
617 format!(
618 "{:?}",
619 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err())
620 ),
621 "ParseFileTimeError(ParseIntError { kind: PosOverflow })"
622 );
623 }
624
625 #[test]
626 fn parse_file_time_error_equality() {
627 assert_eq!(
628 ParseFileTimeError::new(u64::from_str("").unwrap_err()),
629 ParseFileTimeError::new(u64::from_str("").unwrap_err())
630 );
631 assert_ne!(
632 ParseFileTimeError::new(u64::from_str("").unwrap_err()),
633 ParseFileTimeError::new(u64::from_str("a").unwrap_err())
634 );
635 assert_ne!(
636 ParseFileTimeError::new(u64::from_str("").unwrap_err()),
637 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err())
638 );
639 assert_ne!(
640 ParseFileTimeError::new(u64::from_str("a").unwrap_err()),
641 ParseFileTimeError::new(u64::from_str("").unwrap_err())
642 );
643 assert_eq!(
644 ParseFileTimeError::new(u64::from_str("a").unwrap_err()),
645 ParseFileTimeError::new(u64::from_str("a").unwrap_err())
646 );
647 assert_ne!(
648 ParseFileTimeError::new(u64::from_str("a").unwrap_err()),
649 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err())
650 );
651 assert_ne!(
652 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err()),
653 ParseFileTimeError::new(u64::from_str("").unwrap_err())
654 );
655 assert_ne!(
656 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err()),
657 ParseFileTimeError::new(u64::from_str("a").unwrap_err())
658 );
659 assert_eq!(
660 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err()),
661 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err())
662 );
663 }
664
665 #[test]
666 fn display_parse_file_time_error() {
667 assert_eq!(
668 format!(
669 "{}",
670 ParseFileTimeError::new(u64::from_str("").unwrap_err())
671 ),
672 "cannot parse integer from empty string"
673 );
674 assert_eq!(
675 format!(
676 "{}",
677 ParseFileTimeError::new(u64::from_str("a").unwrap_err())
678 ),
679 "invalid digit found in string"
680 );
681 assert_eq!(
682 format!(
683 "{}",
684 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err())
685 ),
686 "date and time is after `+60056-05-28 05:36:10.955161500 UTC`"
687 );
688 }
689
690 #[test]
691 fn source_parse_file_time_error() {
692 assert_eq!(
693 ParseFileTimeError::new(u64::from_str("").unwrap_err())
694 .source()
695 .unwrap()
696 .downcast_ref::<ParseIntError>()
697 .unwrap()
698 .kind(),
699 &IntErrorKind::Empty
700 );
701 assert_eq!(
702 ParseFileTimeError::new(u64::from_str("a").unwrap_err())
703 .source()
704 .unwrap()
705 .downcast_ref::<ParseIntError>()
706 .unwrap()
707 .kind(),
708 &IntErrorKind::InvalidDigit
709 );
710 assert_eq!(
711 ParseFileTimeError::new(u64::from_str("18446744073709551616").unwrap_err())
712 .source()
713 .unwrap()
714 .downcast_ref::<ParseIntError>()
715 .unwrap()
716 .kind(),
717 &IntErrorKind::PosOverflow
718 );
719 }
720}