Skip to content

Commit 219b405

Browse files
committed
Add from bytes impl
1 parent 946d05f commit 219b405

File tree

3 files changed

+84
-44
lines changed

3 files changed

+84
-44
lines changed

src/collections/array_set.rs

Lines changed: 74 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use core::{cmp::Ordering, mem::size_of, ops::Deref, ptr::copy};
22

3-
use crate::transmute::{cast_slice_unchecked, cast_slice_unchecked_mut, Transmute};
3+
use crate::{
4+
error::{Result, TranslationError},
5+
from_bytes::{FromBytes, FromBytesMut},
6+
transmute::{cast_slice_unchecked, cast_slice_unchecked_mut, Transmute},
7+
};
48

59
pub trait Prefix: Transmute {
610
fn as_usize(&self) -> usize;
@@ -62,27 +66,6 @@ where
6266
values: &'a [V],
6367
}
6468

65-
impl<'a, P, V> ArraySet<'a, P, V>
66-
where
67-
P: Prefix,
68-
V: Copy + Clone + Default + PartialOrd + Transmute,
69-
{
70-
/// Loads a sorted array from its byte representation.
71-
///
72-
/// # Safety
73-
///
74-
/// This method does not check the length of the byte slice nor its
75-
/// alignment. The caller must ensure that the byte slice contains a
76-
/// valid representation.
77-
pub unsafe fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
78-
let (length, values) = bytes.split_at(size_of::<P>());
79-
Self {
80-
length: P::transmute_unchecked(length),
81-
values: cast_slice_unchecked(values),
82-
}
83-
}
84-
}
85-
8669
/// Macro to implement the read-only interface for an array set type.
8770
macro_rules! readonly_impl {
8871
( $name:tt ) => {
@@ -202,26 +185,11 @@ where
202185
values: &'a mut [V],
203186
}
204187

205-
impl<'a, P, V> ArraySetMut<'a, P, V>
188+
impl<P, V> ArraySetMut<'_, P, V>
206189
where
207190
P: Prefix,
208191
V: Default + Copy + Clone + Ord + Transmute,
209192
{
210-
/// Loads a sorted array from its byte representation.
211-
///
212-
/// # Safety
213-
///
214-
/// This method does not check the length of the byte slice nor its
215-
/// alignment. The caller must ensure that the byte slice contains a
216-
/// valid representation.
217-
pub unsafe fn from_bytes_unchecked_mut(bytes: &'a mut [u8]) -> Self {
218-
let (length, values) = bytes.split_at_mut(size_of::<P>());
219-
Self {
220-
length: P::transmute_unchecked_mut(length),
221-
values: cast_slice_unchecked_mut(values),
222-
}
223-
}
224-
225193
/// Returns a mutable reference to the value in the set, if any, that is equal to the
226194
/// given value.
227195
///
@@ -311,6 +279,74 @@ where
311279
}
312280
}
313281

282+
unsafe impl<'a, P, V> FromBytes<'a> for ArraySet<'a, P, V>
283+
where
284+
P: Prefix,
285+
V: Default + Copy + Clone + Ord + Transmute,
286+
{
287+
/// Loads a sorted array from its byte representation.
288+
fn from_bytes(bytes: &'a [u8]) -> Result<Self> {
289+
if bytes.len() < size_of::<P>() {
290+
return Err(TranslationError::InvalidLength);
291+
}
292+
293+
if align_of_val(bytes) != align_of::<Self>() {
294+
return Err(TranslationError::InvalidLength);
295+
}
296+
297+
Ok(unsafe { Self::from_bytes_unchecked(bytes) })
298+
}
299+
300+
/// Loads a sorted array from its byte representation.
301+
///
302+
/// # Safety
303+
///
304+
/// This method does not check the length of the byte slice nor its
305+
/// alignment. The caller must ensure that the byte slice contains a
306+
/// valid representation.
307+
unsafe fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
308+
let (length, values) = bytes.split_at(size_of::<P>());
309+
Self {
310+
length: P::transmute_unchecked(length),
311+
values: cast_slice_unchecked(values),
312+
}
313+
}
314+
}
315+
316+
unsafe impl<'a, P, V> FromBytesMut<'a> for ArraySetMut<'a, P, V>
317+
where
318+
P: Prefix,
319+
V: Default + Copy + Clone + Ord + Transmute,
320+
{
321+
/// Loads a sorted array from its byte representation.
322+
fn from_bytes_mut(bytes: &'a mut [u8]) -> Result<Self> {
323+
if bytes.len() < size_of::<P>() {
324+
return Err(TranslationError::InvalidLength);
325+
}
326+
327+
if align_of_val(bytes) != align_of::<Self>() {
328+
return Err(TranslationError::InvalidLength);
329+
}
330+
331+
Ok(unsafe { Self::from_bytes_unchecked_mut(bytes) })
332+
}
333+
334+
/// Loads a sorted array from its byte representation.
335+
///
336+
/// # Safety
337+
///
338+
/// This method does not check the length of the byte slice nor its
339+
/// alignment. The caller must ensure that the byte slice contains a
340+
/// valid representation.
341+
unsafe fn from_bytes_unchecked_mut(bytes: &'a mut [u8]) -> Self {
342+
let (length, values) = bytes.split_at_mut(size_of::<P>());
343+
Self {
344+
length: P::transmute_unchecked_mut(length),
345+
values: cast_slice_unchecked_mut(values),
346+
}
347+
}
348+
}
349+
314350
readonly_impl!(ArraySet);
315351
readonly_impl!(ArraySetMut);
316352

src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pub enum TranslationError {
1616

1717
/// Invalid value found for type.
1818
InvalidValue,
19+
20+
/// Misaligned memory for translation.
21+
Misaligned,
1922
}
2023

2124
impl Error for TranslationError {}
@@ -25,6 +28,7 @@ impl Display for TranslationError {
2528
match self {
2629
TranslationError::InvalidLength => write!(f, "invalid length for translation"),
2730
TranslationError::InvalidValue => write!(f, "invalid value found for type"),
31+
TranslationError::Misaligned => write!(f, "misaligned memory for translation"),
2832
}
2933
}
3034
}

src/from_bytes.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ use crate::error::Result;
66
///
77
/// Types implementing this trait must ensure that the byte slice is
88
/// properly aligned and that the bytes represent a valid instance of the type.
9-
pub unsafe trait FromBytes<T> {
9+
pub unsafe trait FromBytes<'bytes>: Sized {
1010
/// Creates an instance of `Self` from a byte slice.
1111
///
1212
/// # Errors
1313
///
1414
/// Returns an error if the byte slice does not have the correct length.
15-
fn from_bytes(bytes: &[u8]) -> Result<T>;
15+
fn from_bytes(bytes: &'bytes [u8]) -> Result<Self>;
1616

1717
/// Creates an instance of `Self` from a byte slice.
1818
///
1919
/// # Safety
2020
///
2121
/// The caller must ensure that `bytes` contains a valid representation of
2222
/// the implementing type.
23-
unsafe fn from_bytes_unchecked(bytes: &[u8]) -> T;
23+
unsafe fn from_bytes_unchecked(bytes: &'bytes [u8]) -> Self;
2424
}
2525

2626
/// Marker trait for types that can be created from a mutable byte slice.
@@ -32,19 +32,19 @@ pub unsafe trait FromBytes<T> {
3232
///
3333
/// Caution should be taken when the type offers interior mutability, given that
3434
/// the source byte slice is mutable.
35-
pub unsafe trait FromBytesMut<T> {
35+
pub unsafe trait FromBytesMut<'bytes>: Sized {
3636
/// Creates an instance of `Self` from a byte slice.
3737
///
3838
/// # Errors
3939
///
4040
/// Returns an error if the byte slice does not have the correct length.
41-
fn from_bytes_mut(bytes: &mut [u8]) -> Result<T>;
41+
fn from_bytes_mut(bytes: &'bytes mut [u8]) -> Result<Self>;
4242

4343
/// Creates an instance of `Self` from a byte slice.
4444
///
4545
/// # Safety
4646
///
4747
/// The caller must ensure that `bytes` contains a valid representation of
4848
/// the implementing type.
49-
fn from_bytes_unchecked_mut(bytes: &mut [u8]) -> T;
49+
unsafe fn from_bytes_unchecked_mut(bytes: &'bytes mut [u8]) -> Self;
5050
}

0 commit comments

Comments
 (0)