nt_time/file_time/
str.rs

1// SPDX-FileCopyrightText: 2023 Shun Sakai
2//
3// SPDX-License-Identifier: Apache-2.0 OR MIT
4
5//! Utilities for string related operations.
6
7use core::str::FromStr;
8
9use super::FileTime;
10use crate::error::ParseFileTimeError;
11
12impl FileTime {
13    /// Parses a `FileTime` from a string slice with digits in a given base.
14    ///
15    /// The string is expected to be an optional `+` sign followed by only
16    /// digits. Leading and trailing non-digit characters (including whitespace)
17    /// represent an error. Underscores (which are accepted in Rust literals)
18    /// also represent an error.
19    ///
20    /// Digits are a subset of these characters, depending on `radix`:
21    ///
22    /// - `0-9`
23    /// - `a-z`
24    /// - `A-Z`
25    ///
26    /// # Errors
27    ///
28    /// Returns [`Err`] if [`u64::from_str_radix`] returns an error.
29    ///
30    /// # Panics
31    ///
32    /// Panics if `radix` is not in the range from 2 to 36.
33    ///
34    /// # Examples
35    ///
36    /// ```
37    /// # use nt_time::FileTime;
38    /// #
39    /// assert_eq!(
40    ///     FileTime::from_str_radix("0", 2),
41    ///     Ok(FileTime::NT_TIME_EPOCH)
42    /// );
43    /// assert_eq!(
44    ///     FileTime::from_str_radix("6355435732517500000", 8),
45    ///     Ok(FileTime::UNIX_EPOCH)
46    /// );
47    /// assert_eq!(
48    ///     FileTime::from_str_radix("+9223372036854775807", 10),
49    ///     Ok(FileTime::SIGNED_MAX)
50    /// );
51    /// assert_eq!(
52    ///     FileTime::from_str_radix("+ffffffffffffffff", 16),
53    ///     Ok(FileTime::MAX)
54    /// );
55    ///
56    /// assert!(FileTime::from_str_radix("8", 8).is_err());
57    ///
58    /// assert!(FileTime::from_str_radix("", 16).is_err());
59    ///
60    /// assert!(FileTime::from_str_radix("Z", 16).is_err());
61    /// assert!(FileTime::from_str_radix("_", 16).is_err());
62    /// assert!(FileTime::from_str_radix("-1", 16).is_err());
63    /// assert!(FileTime::from_str_radix("+", 16).is_err());
64    /// assert!(FileTime::from_str_radix("0 ", 16).is_err());
65    ///
66    /// assert!(FileTime::from_str_radix("3W5E11264SGSG", 36).is_err());
67    /// ```
68    ///
69    /// `radix` must be greater than or equal to 2:
70    ///
71    /// ```should_panic
72    /// # use nt_time::FileTime;
73    /// #
74    /// let _ = FileTime::from_str_radix("0", 1);
75    /// ```
76    ///
77    /// `radix` must be less than or equal to 36:
78    ///
79    /// ```should_panic
80    /// # use nt_time::FileTime;
81    /// #
82    /// let _ = FileTime::from_str_radix("0", 37);
83    /// ```
84    #[inline]
85    pub const fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseFileTimeError> {
86        match u64::from_str_radix(src, radix) {
87            Ok(ft) => Ok(Self::new(ft)),
88            Err(err) => Err(ParseFileTimeError::new(err)),
89        }
90    }
91}
92
93impl FromStr for FileTime {
94    type Err = ParseFileTimeError;
95
96    /// Parses a string `src` to return a value of `FileTime`.
97    ///
98    /// <div class="warning">
99    ///
100    /// The string is expected to be a decimal non-negative integer. If the
101    /// string is not a decimal integer, use [`FileTime::from_str_radix`]
102    /// instead.
103    ///
104    /// </div>
105    ///
106    /// # Errors
107    ///
108    /// Returns [`Err`] if [`u64::from_str`] returns an error.
109    ///
110    /// # Examples
111    ///
112    /// ```
113    /// # use core::str::FromStr;
114    /// #
115    /// # use nt_time::FileTime;
116    /// #
117    /// assert_eq!(FileTime::from_str("0"), Ok(FileTime::NT_TIME_EPOCH));
118    /// assert_eq!(
119    ///     FileTime::from_str("116444736000000000"),
120    ///     Ok(FileTime::UNIX_EPOCH)
121    /// );
122    /// assert_eq!(
123    ///     FileTime::from_str("+9223372036854775807"),
124    ///     Ok(FileTime::SIGNED_MAX)
125    /// );
126    /// assert_eq!(
127    ///     FileTime::from_str("+18446744073709551615"),
128    ///     Ok(FileTime::MAX)
129    /// );
130    ///
131    /// assert!(FileTime::from_str("").is_err());
132    ///
133    /// assert!(FileTime::from_str("a").is_err());
134    /// assert!(FileTime::from_str("_").is_err());
135    /// assert!(FileTime::from_str("-1").is_err());
136    /// assert!(FileTime::from_str("+").is_err());
137    /// assert!(FileTime::from_str("0 ").is_err());
138    ///
139    /// assert!(FileTime::from_str("18446744073709551616").is_err());
140    /// ```
141    #[inline]
142    fn from_str(src: &str) -> Result<Self, Self::Err> {
143        Self::from_str_radix(src, 10)
144    }
145}
146
147#[cfg(test)]
148mod tests {
149    use core::{
150        error::Error,
151        num::{IntErrorKind, ParseIntError},
152    };
153
154    use super::*;
155
156    #[test]
157    fn from_str_radix() {
158        assert_eq!(
159            FileTime::from_str_radix("0", 2).unwrap(),
160            FileTime::NT_TIME_EPOCH
161        );
162        assert_eq!(
163            FileTime::from_str_radix("+0", 2).unwrap(),
164            FileTime::NT_TIME_EPOCH
165        );
166        assert_eq!(
167            FileTime::from_str_radix(
168                "110011101101100011101111011010101001111101000000000000000",
169                2
170            )
171            .unwrap(),
172            FileTime::UNIX_EPOCH
173        );
174        assert_eq!(
175            FileTime::from_str_radix(
176                "+110011101101100011101111011010101001111101000000000000000",
177                2
178            )
179            .unwrap(),
180            FileTime::UNIX_EPOCH
181        );
182        assert_eq!(
183            FileTime::from_str_radix(
184                "111111111111111111111111111111111111111111111111111111111111111",
185                2
186            )
187            .unwrap(),
188            FileTime::SIGNED_MAX
189        );
190        assert_eq!(
191            FileTime::from_str_radix(
192                "+111111111111111111111111111111111111111111111111111111111111111",
193                2
194            )
195            .unwrap(),
196            FileTime::SIGNED_MAX
197        );
198        assert_eq!(
199            FileTime::from_str_radix(
200                "1111111111111111111111111111111111111111111111111111111111111111",
201                2
202            )
203            .unwrap(),
204            FileTime::MAX
205        );
206        assert_eq!(
207            FileTime::from_str_radix(
208                "+1111111111111111111111111111111111111111111111111111111111111111",
209                2
210            )
211            .unwrap(),
212            FileTime::MAX
213        );
214        assert_eq!(
215            FileTime::from_str_radix("0", 8).unwrap(),
216            FileTime::NT_TIME_EPOCH
217        );
218        assert_eq!(
219            FileTime::from_str_radix("+0", 8).unwrap(),
220            FileTime::NT_TIME_EPOCH
221        );
222        assert_eq!(
223            FileTime::from_str_radix("6355435732517500000", 8).unwrap(),
224            FileTime::UNIX_EPOCH
225        );
226        assert_eq!(
227            FileTime::from_str_radix("+6355435732517500000", 8).unwrap(),
228            FileTime::UNIX_EPOCH
229        );
230        assert_eq!(
231            FileTime::from_str_radix("777777777777777777777", 8).unwrap(),
232            FileTime::SIGNED_MAX
233        );
234        assert_eq!(
235            FileTime::from_str_radix("+777777777777777777777", 8).unwrap(),
236            FileTime::SIGNED_MAX
237        );
238        assert_eq!(
239            FileTime::from_str_radix("1777777777777777777777", 8).unwrap(),
240            FileTime::MAX
241        );
242        assert_eq!(
243            FileTime::from_str_radix("+1777777777777777777777", 8).unwrap(),
244            FileTime::MAX
245        );
246        assert_eq!(
247            FileTime::from_str_radix("0", 10).unwrap(),
248            FileTime::NT_TIME_EPOCH
249        );
250        assert_eq!(
251            FileTime::from_str_radix("+0", 10).unwrap(),
252            FileTime::NT_TIME_EPOCH
253        );
254        assert_eq!(
255            FileTime::from_str_radix("116444736000000000", 10).unwrap(),
256            FileTime::UNIX_EPOCH
257        );
258        assert_eq!(
259            FileTime::from_str_radix("+116444736000000000", 10).unwrap(),
260            FileTime::UNIX_EPOCH
261        );
262        assert_eq!(
263            FileTime::from_str_radix("9223372036854775807", 10).unwrap(),
264            FileTime::SIGNED_MAX
265        );
266        assert_eq!(
267            FileTime::from_str_radix("+9223372036854775807", 10).unwrap(),
268            FileTime::SIGNED_MAX
269        );
270        assert_eq!(
271            FileTime::from_str_radix("18446744073709551615", 10).unwrap(),
272            FileTime::MAX
273        );
274        assert_eq!(
275            FileTime::from_str_radix("+18446744073709551615", 10).unwrap(),
276            FileTime::MAX
277        );
278        assert_eq!(
279            FileTime::from_str_radix("0", 16).unwrap(),
280            FileTime::NT_TIME_EPOCH
281        );
282        assert_eq!(
283            FileTime::from_str_radix("+0", 16).unwrap(),
284            FileTime::NT_TIME_EPOCH
285        );
286        assert_eq!(
287            FileTime::from_str_radix("19db1ded53e8000", 16).unwrap(),
288            FileTime::UNIX_EPOCH
289        );
290        assert_eq!(
291            FileTime::from_str_radix("19DB1DED53E8000", 16).unwrap(),
292            FileTime::UNIX_EPOCH
293        );
294        assert_eq!(
295            FileTime::from_str_radix("+19db1ded53e8000", 16).unwrap(),
296            FileTime::UNIX_EPOCH
297        );
298        assert_eq!(
299            FileTime::from_str_radix("+19DB1DED53E8000", 16).unwrap(),
300            FileTime::UNIX_EPOCH
301        );
302        assert_eq!(
303            FileTime::from_str_radix("7fffffffffffffff", 16).unwrap(),
304            FileTime::SIGNED_MAX
305        );
306        assert_eq!(
307            FileTime::from_str_radix("7FFFFFFFFFFFFFFF", 16).unwrap(),
308            FileTime::SIGNED_MAX
309        );
310        assert_eq!(
311            FileTime::from_str_radix("+7fffffffffffffff", 16).unwrap(),
312            FileTime::SIGNED_MAX
313        );
314        assert_eq!(
315            FileTime::from_str_radix("+7FFFFFFFFFFFFFFF", 16).unwrap(),
316            FileTime::SIGNED_MAX
317        );
318        assert_eq!(
319            FileTime::from_str_radix("ffffffffffffffff", 16).unwrap(),
320            FileTime::MAX
321        );
322        assert_eq!(
323            FileTime::from_str_radix("FFFFFFFFFFFFFFFF", 16).unwrap(),
324            FileTime::MAX
325        );
326        assert_eq!(
327            FileTime::from_str_radix("+ffffffffffffffff", 16).unwrap(),
328            FileTime::MAX
329        );
330        assert_eq!(
331            FileTime::from_str_radix("+FFFFFFFFFFFFFFFF", 16).unwrap(),
332            FileTime::MAX
333        );
334        assert_eq!(
335            FileTime::from_str_radix("0", 36).unwrap(),
336            FileTime::NT_TIME_EPOCH
337        );
338        assert_eq!(
339            FileTime::from_str_radix("+0", 36).unwrap(),
340            FileTime::NT_TIME_EPOCH
341        );
342        assert_eq!(
343            FileTime::from_str_radix("vuk7p84etc0", 36).unwrap(),
344            FileTime::UNIX_EPOCH
345        );
346        assert_eq!(
347            FileTime::from_str_radix("VUK7P84ETC0", 36).unwrap(),
348            FileTime::UNIX_EPOCH
349        );
350        assert_eq!(
351            FileTime::from_str_radix("+vuk7p84etc0", 36).unwrap(),
352            FileTime::UNIX_EPOCH
353        );
354        assert_eq!(
355            FileTime::from_str_radix("+VUK7P84ETC0", 36).unwrap(),
356            FileTime::UNIX_EPOCH
357        );
358        assert_eq!(
359            FileTime::from_str_radix("1y2p0ij32e8e7", 36).unwrap(),
360            FileTime::SIGNED_MAX
361        );
362        assert_eq!(
363            FileTime::from_str_radix("1Y2P0IJ32E8E7", 36).unwrap(),
364            FileTime::SIGNED_MAX
365        );
366        assert_eq!(
367            FileTime::from_str_radix("+1y2p0ij32e8e7", 36).unwrap(),
368            FileTime::SIGNED_MAX
369        );
370        assert_eq!(
371            FileTime::from_str_radix("+1Y2P0IJ32E8E7", 36).unwrap(),
372            FileTime::SIGNED_MAX
373        );
374        assert_eq!(
375            FileTime::from_str_radix("3w5e11264sgsf", 36).unwrap(),
376            FileTime::MAX
377        );
378        assert_eq!(
379            FileTime::from_str_radix("3W5E11264SGSF", 36).unwrap(),
380            FileTime::MAX
381        );
382        assert_eq!(
383            FileTime::from_str_radix("+3w5e11264sgsf", 36).unwrap(),
384            FileTime::MAX
385        );
386        assert_eq!(
387            FileTime::from_str_radix("+3W5E11264SGSF", 36).unwrap(),
388            FileTime::MAX
389        );
390    }
391
392    #[test]
393    fn from_str_radix_with_invalid_digit_radix() {
394        assert_eq!(
395            FileTime::from_str_radix("2", 2)
396                .unwrap_err()
397                .source()
398                .unwrap()
399                .downcast_ref::<ParseIntError>()
400                .unwrap()
401                .kind(),
402            &IntErrorKind::InvalidDigit
403        );
404        assert_eq!(
405            FileTime::from_str_radix("8", 8)
406                .unwrap_err()
407                .source()
408                .unwrap()
409                .downcast_ref::<ParseIntError>()
410                .unwrap()
411                .kind(),
412            &IntErrorKind::InvalidDigit
413        );
414        assert_eq!(
415            FileTime::from_str_radix("a", 10)
416                .unwrap_err()
417                .source()
418                .unwrap()
419                .downcast_ref::<ParseIntError>()
420                .unwrap()
421                .kind(),
422            &IntErrorKind::InvalidDigit
423        );
424        assert_eq!(
425            FileTime::from_str_radix("A", 10)
426                .unwrap_err()
427                .source()
428                .unwrap()
429                .downcast_ref::<ParseIntError>()
430                .unwrap()
431                .kind(),
432            &IntErrorKind::InvalidDigit
433        );
434        assert_eq!(
435            FileTime::from_str_radix("g", 16)
436                .unwrap_err()
437                .source()
438                .unwrap()
439                .downcast_ref::<ParseIntError>()
440                .unwrap()
441                .kind(),
442            &IntErrorKind::InvalidDigit
443        );
444        assert_eq!(
445            FileTime::from_str_radix("G", 16)
446                .unwrap_err()
447                .source()
448                .unwrap()
449                .downcast_ref::<ParseIntError>()
450                .unwrap()
451                .kind(),
452            &IntErrorKind::InvalidDigit
453        );
454    }
455
456    #[test]
457    fn from_str_radix_when_empty() {
458        assert_eq!(
459            FileTime::from_str_radix("", 16)
460                .unwrap_err()
461                .source()
462                .unwrap()
463                .downcast_ref::<ParseIntError>()
464                .unwrap()
465                .kind(),
466            &IntErrorKind::Empty
467        );
468    }
469
470    #[test]
471    fn from_str_radix_with_invalid_digit() {
472        assert_eq!(
473            FileTime::from_str_radix("Z", 16)
474                .unwrap_err()
475                .source()
476                .unwrap()
477                .downcast_ref::<ParseIntError>()
478                .unwrap()
479                .kind(),
480            &IntErrorKind::InvalidDigit
481        );
482        assert_eq!(
483            FileTime::from_str_radix("_", 16)
484                .unwrap_err()
485                .source()
486                .unwrap()
487                .downcast_ref::<ParseIntError>()
488                .unwrap()
489                .kind(),
490            &IntErrorKind::InvalidDigit
491        );
492        assert_eq!(
493            FileTime::from_str_radix("-1", 16)
494                .unwrap_err()
495                .source()
496                .unwrap()
497                .downcast_ref::<ParseIntError>()
498                .unwrap()
499                .kind(),
500            &IntErrorKind::InvalidDigit
501        );
502        assert_eq!(
503            FileTime::from_str_radix("+", 16)
504                .unwrap_err()
505                .source()
506                .unwrap()
507                .downcast_ref::<ParseIntError>()
508                .unwrap()
509                .kind(),
510            &IntErrorKind::InvalidDigit
511        );
512        assert_eq!(
513            FileTime::from_str_radix("-", 16)
514                .unwrap_err()
515                .source()
516                .unwrap()
517                .downcast_ref::<ParseIntError>()
518                .unwrap()
519                .kind(),
520            &IntErrorKind::InvalidDigit
521        );
522        assert_eq!(
523            FileTime::from_str_radix(" 0", 16)
524                .unwrap_err()
525                .source()
526                .unwrap()
527                .downcast_ref::<ParseIntError>()
528                .unwrap()
529                .kind(),
530            &IntErrorKind::InvalidDigit
531        );
532        assert_eq!(
533            FileTime::from_str_radix("0 ", 16)
534                .unwrap_err()
535                .source()
536                .unwrap()
537                .downcast_ref::<ParseIntError>()
538                .unwrap()
539                .kind(),
540            &IntErrorKind::InvalidDigit
541        );
542    }
543
544    #[test]
545    fn from_str_radix_when_positive_overflow() {
546        assert_eq!(
547            FileTime::from_str_radix(
548                "10000000000000000000000000000000000000000000000000000000000000000",
549                2
550            )
551            .unwrap_err()
552            .source()
553            .unwrap()
554            .downcast_ref::<ParseIntError>()
555            .unwrap()
556            .kind(),
557            &IntErrorKind::PosOverflow
558        );
559        assert_eq!(
560            FileTime::from_str_radix("2000000000000000000000", 8)
561                .unwrap_err()
562                .source()
563                .unwrap()
564                .downcast_ref::<ParseIntError>()
565                .unwrap()
566                .kind(),
567            &IntErrorKind::PosOverflow
568        );
569        assert_eq!(
570            FileTime::from_str_radix("18446744073709551616", 10)
571                .unwrap_err()
572                .source()
573                .unwrap()
574                .downcast_ref::<ParseIntError>()
575                .unwrap()
576                .kind(),
577            &IntErrorKind::PosOverflow
578        );
579        assert_eq!(
580            FileTime::from_str_radix("10000000000000000", 16)
581                .unwrap_err()
582                .source()
583                .unwrap()
584                .downcast_ref::<ParseIntError>()
585                .unwrap()
586                .kind(),
587            &IntErrorKind::PosOverflow
588        );
589        assert_eq!(
590            FileTime::from_str_radix("3w5e11264sgsg", 36)
591                .unwrap_err()
592                .source()
593                .unwrap()
594                .downcast_ref::<ParseIntError>()
595                .unwrap()
596                .kind(),
597            &IntErrorKind::PosOverflow
598        );
599        assert_eq!(
600            FileTime::from_str_radix("3W5E11264SGSG", 36)
601                .unwrap_err()
602                .source()
603                .unwrap()
604                .downcast_ref::<ParseIntError>()
605                .unwrap()
606                .kind(),
607            &IntErrorKind::PosOverflow
608        );
609    }
610
611    #[test]
612    #[should_panic]
613    fn from_str_radix_when_radix_is_less_than_2() {
614        let _ = FileTime::from_str_radix("0", 1);
615    }
616
617    #[test]
618    #[should_panic]
619    fn from_str_radix_when_radix_is_greater_than_36() {
620        let _ = FileTime::from_str_radix("0", 37);
621    }
622
623    #[test]
624    const fn from_str_radix_is_const_fn() {
625        const _: Result<FileTime, ParseFileTimeError> = FileTime::from_str_radix("0", 2);
626    }
627
628    #[test]
629    fn from_str() {
630        assert_eq!(FileTime::from_str("0").unwrap(), FileTime::NT_TIME_EPOCH);
631        assert_eq!(FileTime::from_str("+0").unwrap(), FileTime::NT_TIME_EPOCH);
632        assert_eq!(
633            FileTime::from_str("116444736000000000").unwrap(),
634            FileTime::UNIX_EPOCH
635        );
636        assert_eq!(
637            FileTime::from_str("+116444736000000000").unwrap(),
638            FileTime::UNIX_EPOCH
639        );
640        assert_eq!(
641            FileTime::from_str("9223372036854775807").unwrap(),
642            FileTime::SIGNED_MAX
643        );
644        assert_eq!(
645            FileTime::from_str("+9223372036854775807").unwrap(),
646            FileTime::SIGNED_MAX
647        );
648        assert_eq!(
649            FileTime::from_str("18446744073709551615").unwrap(),
650            FileTime::MAX
651        );
652        assert_eq!(
653            FileTime::from_str("+18446744073709551615").unwrap(),
654            FileTime::MAX
655        );
656    }
657
658    #[cfg(feature = "std")]
659    #[test_strategy::proptest]
660    fn from_str_roundtrip(#[strategy(r"\+?[0-9]{1,19}")] s: std::string::String) {
661        use proptest::prop_assert_eq;
662
663        let ft = s.parse().unwrap();
664        prop_assert_eq!(FileTime::from_str(&s).unwrap(), FileTime::new(ft));
665    }
666
667    #[test]
668    fn from_str_when_empty() {
669        assert_eq!(
670            FileTime::from_str("")
671                .unwrap_err()
672                .source()
673                .unwrap()
674                .downcast_ref::<ParseIntError>()
675                .unwrap()
676                .kind(),
677            &IntErrorKind::Empty
678        );
679    }
680
681    #[test]
682    fn from_str_with_invalid_digit() {
683        assert_eq!(
684            FileTime::from_str("a")
685                .unwrap_err()
686                .source()
687                .unwrap()
688                .downcast_ref::<ParseIntError>()
689                .unwrap()
690                .kind(),
691            &IntErrorKind::InvalidDigit
692        );
693        assert_eq!(
694            FileTime::from_str("_")
695                .unwrap_err()
696                .source()
697                .unwrap()
698                .downcast_ref::<ParseIntError>()
699                .unwrap()
700                .kind(),
701            &IntErrorKind::InvalidDigit
702        );
703        assert_eq!(
704            FileTime::from_str("-1")
705                .unwrap_err()
706                .source()
707                .unwrap()
708                .downcast_ref::<ParseIntError>()
709                .unwrap()
710                .kind(),
711            &IntErrorKind::InvalidDigit
712        );
713        assert_eq!(
714            FileTime::from_str("+")
715                .unwrap_err()
716                .source()
717                .unwrap()
718                .downcast_ref::<ParseIntError>()
719                .unwrap()
720                .kind(),
721            &IntErrorKind::InvalidDigit
722        );
723        assert_eq!(
724            FileTime::from_str("-")
725                .unwrap_err()
726                .source()
727                .unwrap()
728                .downcast_ref::<ParseIntError>()
729                .unwrap()
730                .kind(),
731            &IntErrorKind::InvalidDigit
732        );
733        assert_eq!(
734            FileTime::from_str(" 0")
735                .unwrap_err()
736                .source()
737                .unwrap()
738                .downcast_ref::<ParseIntError>()
739                .unwrap()
740                .kind(),
741            &IntErrorKind::InvalidDigit
742        );
743        assert_eq!(
744            FileTime::from_str("0 ")
745                .unwrap_err()
746                .source()
747                .unwrap()
748                .downcast_ref::<ParseIntError>()
749                .unwrap()
750                .kind(),
751            &IntErrorKind::InvalidDigit
752        );
753    }
754
755    #[cfg(feature = "std")]
756    #[test_strategy::proptest]
757    fn from_str_with_invalid_digit_roundtrip(
758        #[strategy(r"-[0-9]+|[^0-9]+")] s: std::string::String,
759    ) {
760        use proptest::prop_assert;
761
762        prop_assert!(FileTime::from_str(&s).is_err());
763    }
764
765    #[test]
766    fn from_str_when_positive_overflow() {
767        assert_eq!(
768            FileTime::from_str("18446744073709551616")
769                .unwrap_err()
770                .source()
771                .unwrap()
772                .downcast_ref::<ParseIntError>()
773                .unwrap()
774                .kind(),
775            &IntErrorKind::PosOverflow
776        );
777    }
778}