From aeeabd7422eebb2221adf96eca761df8f9d40fbb Mon Sep 17 00:00:00 2001 From: Kaido Kert Date: Sat, 28 Sep 2024 17:54:16 -0700 Subject: [PATCH] Implement FromBytes (#39) --- Cargo.toml | 1 + src/fixeduint.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++ src/machineword.rs | 1 + 3 files changed, 60 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 496bcd1..d2b1e97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ default-features = false [dependencies.zeroize] version = "1.8.1" optional = true +default-features = false [profile.dev] opt-level = 0 diff --git a/src/fixeduint.rs b/src/fixeduint.rs index 0501444..356d7ae 100644 --- a/src/fixeduint.rs +++ b/src/fixeduint.rs @@ -1406,6 +1406,14 @@ pub struct BytesHolder { array: [T; N], } +impl Default for BytesHolder { + fn default() -> Self { + Self { + array: core::array::from_fn(|_| T::default()), + } + } +} + #[cfg(feature = "use-unsafe")] impl BytesHolder { // Converts internal storage to a mutable byte slice @@ -1480,6 +1488,22 @@ where } } +#[cfg(feature = "use-unsafe")] +impl num_traits::FromBytes for FixedUInt +where + T: core::fmt::Debug, +{ + type Bytes = BytesHolder; + + fn from_be_bytes(bytes: &Self::Bytes) -> Self { + Self::from_be_bytes(bytes.as_ref()) + } + + fn from_le_bytes(bytes: &Self::Bytes) -> Self { + Self::from_le_bytes(bytes.as_ref()) + } +} + #[cfg(test)] mod tests { use super::FixedUInt as Bn; @@ -1755,4 +1779,38 @@ mod tests { &[0x12, 0x34, 0x56, 0x78], ); } + + fn from_helper(input: &[u8], expected: T) + where + T: num_traits::FromBytes + core::fmt::Debug + core::cmp::PartialEq, + T::Bytes: num_traits::ops::bytes::NumBytes + Default + core::fmt::Debug, + { + let mut bytes = T::Bytes::default(); + bytes.as_mut().copy_from_slice(input); + let result = T::from_be_bytes(&bytes); + assert_eq!(result, expected); + bytes.as_mut().reverse(); + let result = T::from_le_bytes(&bytes); + assert_eq!(result, expected); + } + + #[cfg(feature = "use-unsafe")] + #[test] + fn test_from_bytes() { + from_helper(&[0xAB_u8], 0xAB_u8); + from_helper(&[0xAB, 0xCD], 0xABCD_u16); + from_helper(&[0x12, 0x34, 0x56, 0x78], 0x12345678_u32); + from_helper( + &[0x12, 0x34, 0x56, 0x78], + FixedUInt::::from_u32(0x12345678).unwrap(), + ); + from_helper( + &[0x12, 0x34, 0x56, 0x78], + FixedUInt::::from_u32(0x12345678).unwrap(), + ); + from_helper( + &[0x12, 0x34, 0x56, 0x78], + FixedUInt::::from_u32(0x12345678).unwrap(), + ); + } } diff --git a/src/machineword.rs b/src/machineword.rs index c3647d4..c2ba0cf 100644 --- a/src/machineword.rs +++ b/src/machineword.rs @@ -24,6 +24,7 @@ pub trait MachineWord: + core::ops::BitXorAssign + num_traits::FromBytes + num_traits::ToBytes + + Default { type DoubleWord: num_traits::PrimInt; fn to_double(self) -> Self::DoubleWord;