docs(zerocopy): fix docstring warnings

Signed-off-by: Paul Spooren <mail@aparcar.org>
This commit is contained in:
Paul Spooren
2024-11-06 17:31:37 +01:00
parent ca7df013d5
commit 0836a2eb28
3 changed files with 31 additions and 0 deletions

View File

@@ -7,56 +7,68 @@ use zeroize::Zeroize;
use crate::zeroize::ZeroizedExt;
#[derive(Clone, Copy, Debug)]
/// A convenience type for working with mutable references to a buffer and an
/// expected target type.
pub struct RefMaker<B: Sized, T> {
buf: B,
_phantom_t: PhantomData<T>,
}
impl<B, T> RefMaker<B, T> {
/// Creates a new RefMaker with the given buffer
pub fn new(buf: B) -> Self {
let _phantom_t = PhantomData;
Self { buf, _phantom_t }
}
/// Returns the size in bytes needed for target type T
pub const fn target_size() -> usize {
std::mem::size_of::<T>()
}
/// Consumes this RefMaker and returns the inner buffer
pub fn into_buf(self) -> B {
self.buf
}
/// Returns a reference to the inner buffer
pub fn buf(&self) -> &B {
&self.buf
}
/// Returns a mutable reference to the inner buffer
pub fn buf_mut(&mut self) -> &mut B {
&mut self.buf
}
}
impl<B: ByteSlice, T> RefMaker<B, T> {
/// Parses the buffer into a reference of type T
pub fn parse(self) -> anyhow::Result<Ref<B, T>> {
self.ensure_fit()?;
Ref::<B, T>::new(self.buf).context("Parser error!")
}
/// Splits the buffer into a RefMaker containing the first `target_size` bytes and the remaining tail
pub fn from_prefix_with_tail(self) -> anyhow::Result<(Self, B)> {
self.ensure_fit()?;
let (head, tail) = self.buf.split_at(Self::target_size());
Ok((Self::new(head), tail))
}
/// Splits the buffer into two RefMakers, with the first containing the first `target_size` bytes
pub fn split_prefix(self) -> anyhow::Result<(Self, Self)> {
self.ensure_fit()?;
let (head, tail) = self.buf.split_at(Self::target_size());
Ok((Self::new(head), Self::new(tail)))
}
/// Returns a RefMaker containing only the first `target_size` bytes
pub fn from_prefix(self) -> anyhow::Result<Self> {
Ok(Self::from_prefix_with_tail(self)?.0)
}
/// Splits the buffer into a RefMaker containing the last `target_size` bytes and the preceding head
pub fn from_suffix_with_head(self) -> anyhow::Result<(Self, B)> {
self.ensure_fit()?;
let point = self.bytes().len() - Self::target_size();
@@ -64,6 +76,7 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
Ok((Self::new(tail), head))
}
/// Splits the buffer into two RefMakers, with the second containing the last `target_size` bytes
pub fn split_suffix(self) -> anyhow::Result<(Self, Self)> {
self.ensure_fit()?;
let point = self.bytes().len() - Self::target_size();
@@ -71,14 +84,17 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
Ok((Self::new(head), Self::new(tail)))
}
/// Returns a RefMaker containing only the last `target_size` bytes
pub fn from_suffix(self) -> anyhow::Result<Self> {
Ok(Self::from_suffix_with_head(self)?.0)
}
/// Returns a reference to the underlying bytes
pub fn bytes(&self) -> &[u8] {
self.buf().deref()
}
/// Ensures the buffer is large enough to hold type T
pub fn ensure_fit(&self) -> anyhow::Result<()> {
let have = self.bytes().len();
let need = Self::target_size();
@@ -91,10 +107,12 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
}
impl<B: ByteSliceMut, T> RefMaker<B, T> {
/// Creates a zeroed reference of type T from the buffer
pub fn make_zeroized(self) -> anyhow::Result<Ref<B, T>> {
self.zeroized().parse()
}
/// Returns a mutable reference to the underlying bytes
pub fn bytes_mut(&mut self) -> &mut [u8] {
self.buf_mut().deref_mut()
}

View File

@@ -1,10 +1,14 @@
use zerocopy::{ByteSlice, ByteSliceMut, Ref};
/// A trait for converting a `Ref<B, T>` into a `Ref<&[u8], T>`.
pub trait ZerocopyEmancipateExt<B, T> {
/// Converts this reference into a reference backed by a byte slice.
fn emancipate(&self) -> Ref<&[u8], T>;
}
/// A trait for converting a `Ref<B, T>` into a mutable `Ref<&mut [u8], T>`.
pub trait ZerocopyEmancipateMutExt<B, T> {
/// Converts this reference into a mutable reference backed by a byte slice.
fn emancipate_mut(&mut self) -> Ref<&mut [u8], T>;
}

View File

@@ -2,19 +2,24 @@ use zerocopy::{ByteSlice, ByteSliceMut, Ref};
use super::RefMaker;
/// Extension trait for zero-copy slice operations.
pub trait ZerocopySliceExt: Sized + ByteSlice {
/// Creates a new `RefMaker` for the given slice.
fn zk_ref_maker<T>(self) -> RefMaker<Self, T> {
RefMaker::<Self, T>::new(self)
}
/// Parses the slice into a zero-copy reference.
fn zk_parse<T>(self) -> anyhow::Result<Ref<Self, T>> {
self.zk_ref_maker().parse()
}
/// Parses a prefix of the slice into a zero-copy reference.
fn zk_parse_prefix<T>(self) -> anyhow::Result<Ref<Self, T>> {
self.zk_ref_maker().from_prefix()?.parse()
}
/// Parses a suffix of the slice into a zero-copy reference.
fn zk_parse_suffix<T>(self) -> anyhow::Result<Ref<Self, T>> {
self.zk_ref_maker().from_suffix()?.parse()
}
@@ -22,15 +27,19 @@ pub trait ZerocopySliceExt: Sized + ByteSlice {
impl<B: ByteSlice> ZerocopySliceExt for B {}
/// Extension trait for zero-copy slice operations with mutable slices.
pub trait ZerocopyMutSliceExt: ZerocopySliceExt + Sized + ByteSliceMut {
/// Creates a new zeroed reference from the entire slice.
fn zk_zeroized<T>(self) -> anyhow::Result<Ref<Self, T>> {
self.zk_ref_maker().make_zeroized()
}
/// Creates a new zeroed reference from a prefix of the slice.
fn zk_zeroized_from_prefix<T>(self) -> anyhow::Result<Ref<Self, T>> {
self.zk_ref_maker().from_prefix()?.make_zeroized()
}
/// Creates a new zeroed reference from a suffix of the slice.
fn zk_zeroized_from_suffix<T>(self) -> anyhow::Result<Ref<Self, T>> {
self.zk_ref_maker().from_suffix()?.make_zeroized()
}