| //! Extension traits for things either not implemented or not yet stable in the MSRV. |
| |
| /// Equivalent of `foo.parse()` for slices. |
| pub(crate) trait IntegerParseBytes<T> { |
| #[allow(clippy::missing_docs_in_private_items)] |
| fn parse_bytes(&self) -> Option<T>; |
| } |
| |
| impl<T: Integer> IntegerParseBytes<T> for [u8] { |
| fn parse_bytes(&self) -> Option<T> { |
| T::parse_bytes(self) |
| } |
| } |
| |
| /// Marker trait for all integer types, including `NonZero*` |
| pub(crate) trait Integer: Sized { |
| #[allow(clippy::missing_docs_in_private_items)] |
| fn parse_bytes(src: &[u8]) -> Option<Self>; |
| } |
| |
| /// Parse the given types from bytes. |
| macro_rules! impl_parse_bytes { |
| ($($t:ty)*) => ($( |
| impl Integer for $t { |
| #[allow(trivial_numeric_casts)] |
| fn parse_bytes(src: &[u8]) -> Option<Self> { |
| src.iter().try_fold::<Self, _, _>(0, |result, c| { |
| result.checked_mul(10)?.checked_add((c - b'0') as Self) |
| }) |
| } |
| } |
| )*) |
| } |
| impl_parse_bytes! { u8 u16 u32 u128 } |
| |
| /// Parse the given types from bytes. |
| macro_rules! impl_parse_bytes_nonzero { |
| ($($t:ty)*) => {$( |
| impl Integer for $t { |
| fn parse_bytes(src: &[u8]) -> Option<Self> { |
| Self::new(src.parse_bytes()?) |
| } |
| } |
| )*} |
| } |
| |
| impl_parse_bytes_nonzero! { |
| core::num::NonZeroU8 |
| core::num::NonZeroU16 |
| } |