blob: ced7feb03e47bcd035ad3a346b17d9cb5de6ac42 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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 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
}
|