diff --git a/src/core/utils/bytes.rs b/src/core/utils/bytes.rs new file mode 100644 index 00000000..6ebf4c4f --- /dev/null +++ b/src/core/utils/bytes.rs @@ -0,0 +1,29 @@ +use crate::Result; + +#[inline] +#[must_use] +pub fn increment(old: Option<&[u8]>) -> [u8; 8] { + old.map(TryInto::try_into) + .map_or(0_u64, |val| val.map_or(0_u64, u64::from_be_bytes)) + .wrapping_add(1) + .to_be_bytes() +} + +/// Parses the big-endian bytes into an u64. +#[inline] +pub fn u64_from_bytes(bytes: &[u8]) -> Result { + let array: [u8; 8] = bytes.try_into()?; + Ok(u64_from_u8x8(array)) +} + +/// Parses the 8 big-endian bytes into an u64. +#[inline] +#[must_use] +pub fn u64_from_u8(bytes: &[u8]) -> u64 { + let bytes: &[u8; 8] = bytes.try_into().expect("must slice at least 8 bytes"); + u64_from_u8x8(*bytes) +} + +#[inline] +#[must_use] +pub fn u64_from_u8x8(bytes: [u8; 8]) -> u64 { u64::from_be_bytes(bytes) } diff --git a/src/core/utils/hash.rs b/src/core/utils/hash.rs index d1219bfe..9469321f 100644 --- a/src/core/utils/hash.rs +++ b/src/core/utils/hash.rs @@ -12,4 +12,5 @@ pub fn verify_password(password: &str, password_hash: &str) -> Result<()> { } #[inline] +#[must_use] pub fn calculate_hash(keys: &[&[u8]]) -> Vec { sha256::hash(keys) } diff --git a/src/core/utils/mod.rs b/src/core/utils/mod.rs index 1ff36b02..6ebab2c6 100644 --- a/src/core/utils/mod.rs +++ b/src/core/utils/mod.rs @@ -1,3 +1,4 @@ +pub mod bytes; pub mod content_disposition; pub mod debug; pub mod defer; @@ -14,6 +15,7 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; +pub use bytes::{increment, u64_from_bytes, u64_from_u8, u64_from_u8x8}; pub use debug::slice_truncated as debug_slice_truncated; pub use hash::calculate_hash; pub use html::Escape as HtmlEscape; @@ -26,6 +28,18 @@ use crate::Result; pub fn clamp(val: T, min: T, max: T) -> T { cmp::min(cmp::max(val, min), max) } +/// Boilerplate for wraps which are typed to never error. +/// +/// * +#[must_use] +#[inline(always)] +pub fn unwrap_infallible(result: Result) -> T { + match result { + Ok(val) => val, + Err(err) => match err {}, + } +} + #[must_use] #[allow(clippy::as_conversions)] pub fn millis_since_unix_epoch() -> u64 { @@ -35,15 +49,6 @@ pub fn millis_since_unix_epoch() -> u64 { .as_millis() as u64 } -#[inline] -#[must_use] -pub fn increment(old: Option<&[u8]>) -> [u8; 8] { - old.map(TryInto::try_into) - .map_or(0_u64, |val| val.map_or(0_u64, u64::from_be_bytes)) - .wrapping_add(1) - .to_be_bytes() -} - #[must_use] pub fn generate_keypair() -> Vec { let mut value = random_string(8).as_bytes().to_vec(); @@ -54,15 +59,6 @@ pub fn generate_keypair() -> Vec { value } -/// Parses the bytes into an u64. -pub fn u64_from_bytes(bytes: &[u8]) -> Result { - let array: [u8; 8] = bytes.try_into()?; - Ok(u64::from_be_bytes(array)) -} - -} - - #[allow(clippy::impl_trait_in_params)] pub fn common_elements( mut iterators: impl Iterator>>, check_order: impl Fn(&[u8], &[u8]) -> Ordering, @@ -86,15 +82,3 @@ pub fn common_elements( }) })) } - -/// Boilerplate for wraps which are typed to never error. -/// -/// * -#[must_use] -#[inline(always)] -pub fn unwrap_infallible(result: Result) -> T { - match result { - Ok(val) => val, - Err(err) => match err {}, - } -} diff --git a/src/service/rooms/auth_chain/data.rs b/src/service/rooms/auth_chain/data.rs index b2e80b7b..a5771f4a 100644 --- a/src/service/rooms/auth_chain/data.rs +++ b/src/service/rooms/auth_chain/data.rs @@ -38,7 +38,7 @@ impl Data { .map(|chain| { chain .chunks_exact(size_of::()) - .map(|chunk| utils::u64_from_bytes(chunk).expect("byte length is correct")) + .map(utils::u64_from_u8) .collect::>() });