mirror of
https://github.com/rosenpass/rosenpass.git
synced 2025-12-18 13:24:38 +03:00
82 lines
2.7 KiB
Rust
82 lines
2.7 KiB
Rust
//! Extension traits for converting `Ref<B, T>` into references backed by
|
|
//! standard slices.
|
|
|
|
use zerocopy::{ByteSlice, ByteSliceMut, Ref};
|
|
|
|
/// A trait for converting a `Ref<B, T>` into a `Ref<&[u8], T>`.
|
|
///
|
|
/// This can be useful when you need a reference that is tied to a slice rather
|
|
/// than the original buffer type `B`.
|
|
///
|
|
/// Note: This trait is implemented to [`Ref`] of byte slices (`&[u8]`).
|
|
pub trait ZerocopyEmancipateExt<B, T> {
|
|
/// Converts this reference into a reference backed by a plain byte slice.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use std::ops::Deref;
|
|
/// # use zerocopy::{AsBytes, ByteSlice, FromBytes, FromZeroes, Ref};
|
|
/// # use rosenpass_util::zerocopy::ZerocopyEmancipateExt;
|
|
/// #[derive(FromBytes, FromZeroes, AsBytes)]
|
|
/// #[repr(C)]
|
|
/// struct Data(u32);
|
|
/// #[repr(align(4))]
|
|
/// struct AlignedBuf([u8; 4]);
|
|
/// let bytes = AlignedBuf([0xAA, 0xBB, 0xCC, 0xDD]);
|
|
/// let r = Ref::<&[u8], Data>::new(&bytes.0).unwrap();
|
|
/// let emancipated: Ref<&[u8], Data> = r.emancipate(); // same data, but guaranteed &[u8] backing
|
|
/// assert_eq!(emancipated.0, 0xDDCCBBAA);
|
|
/// ```
|
|
fn emancipate(&self) -> Ref<&[u8], T>;
|
|
}
|
|
|
|
/// A trait for converting a `Ref<B, T>` into a mutable `Ref<&mut [u8], T>`.
|
|
///
|
|
/// Similar to [`ZerocopyEmancipateExt`], but for mutable references.
|
|
///
|
|
/// Note: this trait is implemented to [`Ref`] of mutable byte
|
|
/// slices (`&mut [u8]`).
|
|
pub trait ZerocopyEmancipateMutExt<B, T> {
|
|
/// Converts this reference into a mutable reference backed by a plain
|
|
/// mutable byte slice.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use zerocopy::{AsBytes, FromBytes, FromZeroes, Ref};
|
|
/// # use rosenpass_util::zerocopy::{ZerocopyEmancipateMutExt};
|
|
/// #[derive(FromBytes, FromZeroes, AsBytes)]
|
|
/// #[repr(C)]
|
|
/// struct Data(u32);
|
|
/// #[repr(align(4))]
|
|
/// struct AlignedBuf([u8; 4]);
|
|
/// let mut bytes = AlignedBuf([0xAA, 0xBB, 0xCC, 0xDD]);
|
|
/// let mut r = Ref::<&mut [u8], Data>::new(&mut bytes.0).unwrap();
|
|
/// let mut emancipated: Ref<&mut [u8], Data> = r.emancipate_mut(); // same data, but guaranteed &[u8] backing
|
|
/// assert_eq!(emancipated.0, 0xDDCCBBAA);
|
|
/// emancipated.0 = 0x33221100;
|
|
/// drop(emancipated);
|
|
/// assert_eq!(bytes.0, [0x00, 0x11, 0x22, 0x33]);
|
|
/// ```
|
|
fn emancipate_mut(&mut self) -> Ref<&mut [u8], T>;
|
|
}
|
|
|
|
impl<B, T> ZerocopyEmancipateExt<B, T> for Ref<B, T>
|
|
where
|
|
B: ByteSlice,
|
|
{
|
|
fn emancipate(&self) -> Ref<&[u8], T> {
|
|
Ref::new(self.bytes()).unwrap()
|
|
}
|
|
}
|
|
|
|
impl<B, T> ZerocopyEmancipateMutExt<B, T> for Ref<B, T>
|
|
where
|
|
B: ByteSliceMut,
|
|
{
|
|
fn emancipate_mut(&mut self) -> Ref<&mut [u8], T> {
|
|
Ref::new(self.bytes_mut()).unwrap()
|
|
}
|
|
}
|