time/parsing/
shim.rs

1//! Extension traits for things either not implemented or not yet stable in the MSRV.
2
3/// Equivalent of `foo.parse()` for slices.
4pub(crate) trait IntegerParseBytes<T> {
5    #[allow(clippy::missing_docs_in_private_items)]
6    fn parse_bytes(&self) -> Option<T>;
7}
8
9impl<T: Integer> IntegerParseBytes<T> for [u8] {
10    #[inline]
11    fn parse_bytes(&self) -> Option<T> {
12        T::parse_bytes(self)
13    }
14}
15
16/// Marker trait for all integer types, including `NonZero*`
17pub(crate) trait Integer: Sized {
18    #[allow(clippy::missing_docs_in_private_items)]
19    fn parse_bytes(src: &[u8]) -> Option<Self>;
20}
21
22/// Parse the given types from bytes.
23macro_rules! impl_parse_bytes {
24    ($($t:ty)*) => ($(
25        impl Integer for $t {
26            #[allow(trivial_numeric_casts)]
27            #[inline]
28            fn parse_bytes(src: &[u8]) -> Option<Self> {
29                src.iter().try_fold::<Self, _, _>(0, |result, c| {
30                    result.checked_mul(10)?.checked_add((c - b'0') as Self)
31                })
32            }
33        }
34    )*)
35}
36impl_parse_bytes! { u8 u16 u32 u128 }
37
38/// Parse the given types from bytes.
39macro_rules! impl_parse_bytes_nonzero {
40    ($($t:ty)*) => {$(
41        impl Integer for $t {
42            #[inline]
43            fn parse_bytes(src: &[u8]) -> Option<Self> {
44                Self::new(src.parse_bytes()?)
45            }
46        }
47    )*}
48}
49
50impl_parse_bytes_nonzero! {
51    core::num::NonZero<u8>
52    core::num::NonZero<u16>
53}