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