Skip to content

Commit

Permalink
Implement FromBytes (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaidokert authored Sep 29, 2024
1 parent 13a7fdb commit aeeabd7
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ default-features = false
[dependencies.zeroize]
version = "1.8.1"
optional = true
default-features = false

[profile.dev]
opt-level = 0
Expand Down
58 changes: 58 additions & 0 deletions src/fixeduint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,14 @@ pub struct BytesHolder<T: MachineWord, const N: usize> {
array: [T; N],
}

impl<T: MachineWord, const N: usize> Default for BytesHolder<T, N> {
fn default() -> Self {
Self {
array: core::array::from_fn(|_| T::default()),
}
}
}

#[cfg(feature = "use-unsafe")]
impl<T: MachineWord, const N: usize> BytesHolder<T, N> {
// Converts internal storage to a mutable byte slice
Expand Down Expand Up @@ -1480,6 +1488,22 @@ where
}
}

#[cfg(feature = "use-unsafe")]
impl<T: MachineWord, const N: usize> num_traits::FromBytes for FixedUInt<T, N>
where
T: core::fmt::Debug,
{
type Bytes = BytesHolder<T, N>;

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;
Expand Down Expand Up @@ -1755,4 +1779,38 @@ mod tests {
&[0x12, 0x34, 0x56, 0x78],
);
}

fn from_helper<T>(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::<u8, 4>::from_u32(0x12345678).unwrap(),
);
from_helper(
&[0x12, 0x34, 0x56, 0x78],
FixedUInt::<u16, 2>::from_u32(0x12345678).unwrap(),
);
from_helper(
&[0x12, 0x34, 0x56, 0x78],
FixedUInt::<u32, 1>::from_u32(0x12345678).unwrap(),
);
}
}
1 change: 1 addition & 0 deletions src/machineword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit aeeabd7

Please sign in to comment.