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    fn parse_bytes(&self) -> Option<T> {
11        T::parse_bytes(self)
12    }
13}
14
15/// Marker trait for all integer types, including `NonZero*`
16pub(crate) trait Integer: Sized {
17    #[allow(clippy::missing_docs_in_private_items)]
18    fn parse_bytes(src: &[u8]) -> Option<Self>;
19}
20
21/// Parse the given types from bytes.
22macro_rules! impl_parse_bytes {
23    ($($t:ty)*) => ($(
24        impl Integer for $t {
25            #[allow(trivial_numeric_casts)]
26            fn parse_bytes(src: &[u8]) -> Option<Self> {
27                src.iter().try_fold::<Self, _, _>(0, |result, c| {
28                    result.checked_mul(10)?.checked_add((c - b'0') as Self)
29                })
30            }
31        }
32    )*)
33}
34impl_parse_bytes! { u8 u16 u32 u128 }
35
36/// Parse the given types from bytes.
37macro_rules! impl_parse_bytes_nonzero {
38    ($($t:ty)*) => {$(
39        impl Integer for $t {
40            fn parse_bytes(src: &[u8]) -> Option<Self> {
41                Self::new(src.parse_bytes()?)
42            }
43        }
44    )*}
45}
46
47impl_parse_bytes_nonzero! {
48    core::num::NonZeroU8
49    core::num::NonZeroU16
50}