diff options
Diffstat (limited to 'third_party/rust/time/src/parsing/shim.rs')
-rw-r--r-- | third_party/rust/time/src/parsing/shim.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/third_party/rust/time/src/parsing/shim.rs b/third_party/rust/time/src/parsing/shim.rs new file mode 100644 index 0000000000..00aaf4852b --- /dev/null +++ b/third_party/rust/time/src/parsing/shim.rs @@ -0,0 +1,50 @@ +//! 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 } + +/// 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 +} |