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; use crate::zeroize::ZeroizedExt;
#[derive(Clone, Copy, Debug)] #[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> { pub struct RefMaker<B: Sized, T> {
buf: B, buf: B,
_phantom_t: PhantomData<T>, _phantom_t: PhantomData<T>,
} }
impl<B, T> RefMaker<B, T> { impl<B, T> RefMaker<B, T> {
/// Creates a new RefMaker with the given buffer
pub fn new(buf: B) -> Self { pub fn new(buf: B) -> Self {
let _phantom_t = PhantomData; let _phantom_t = PhantomData;
Self { buf, _phantom_t } Self { buf, _phantom_t }
} }
/// Returns the size in bytes needed for target type T
pub const fn target_size() -> usize { pub const fn target_size() -> usize {
std::mem::size_of::<T>() std::mem::size_of::<T>()
} }
/// Consumes this RefMaker and returns the inner buffer
pub fn into_buf(self) -> B { pub fn into_buf(self) -> B {
self.buf self.buf
} }
/// Returns a reference to the inner buffer
pub fn buf(&self) -> &B { pub fn buf(&self) -> &B {
&self.buf &self.buf
} }
/// Returns a mutable reference to the inner buffer
pub fn buf_mut(&mut self) -> &mut B { pub fn buf_mut(&mut self) -> &mut B {
&mut self.buf &mut self.buf
} }
} }
impl<B: ByteSlice, T> RefMaker<B, T> { 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>> { pub fn parse(self) -> anyhow::Result<Ref<B, T>> {
self.ensure_fit()?; self.ensure_fit()?;
Ref::<B, T>::new(self.buf).context("Parser error!") 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)> { pub fn from_prefix_with_tail(self) -> anyhow::Result<(Self, B)> {
self.ensure_fit()?; self.ensure_fit()?;
let (head, tail) = self.buf.split_at(Self::target_size()); let (head, tail) = self.buf.split_at(Self::target_size());
Ok((Self::new(head), tail)) 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)> { pub fn split_prefix(self) -> anyhow::Result<(Self, Self)> {
self.ensure_fit()?; self.ensure_fit()?;
let (head, tail) = self.buf.split_at(Self::target_size()); let (head, tail) = self.buf.split_at(Self::target_size());
Ok((Self::new(head), Self::new(tail))) 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> { pub fn from_prefix(self) -> anyhow::Result<Self> {
Ok(Self::from_prefix_with_tail(self)?.0) 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)> { pub fn from_suffix_with_head(self) -> anyhow::Result<(Self, B)> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.bytes().len() - Self::target_size(); let point = self.bytes().len() - Self::target_size();
@@ -64,6 +76,7 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
Ok((Self::new(tail), head)) 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)> { pub fn split_suffix(self) -> anyhow::Result<(Self, Self)> {
self.ensure_fit()?; self.ensure_fit()?;
let point = self.bytes().len() - Self::target_size(); 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))) 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> { pub fn from_suffix(self) -> anyhow::Result<Self> {
Ok(Self::from_suffix_with_head(self)?.0) Ok(Self::from_suffix_with_head(self)?.0)
} }
/// Returns a reference to the underlying bytes
pub fn bytes(&self) -> &[u8] { pub fn bytes(&self) -> &[u8] {
self.buf().deref() self.buf().deref()
} }
/// Ensures the buffer is large enough to hold type T
pub fn ensure_fit(&self) -> anyhow::Result<()> { pub fn ensure_fit(&self) -> anyhow::Result<()> {
let have = self.bytes().len(); let have = self.bytes().len();
let need = Self::target_size(); let need = Self::target_size();
@@ -91,10 +107,12 @@ impl<B: ByteSlice, T> RefMaker<B, T> {
} }
impl<B: ByteSliceMut, 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>> { pub fn make_zeroized(self) -> anyhow::Result<Ref<B, T>> {
self.zeroized().parse() self.zeroized().parse()
} }
/// Returns a mutable reference to the underlying bytes
pub fn bytes_mut(&mut self) -> &mut [u8] { pub fn bytes_mut(&mut self) -> &mut [u8] {
self.buf_mut().deref_mut() self.buf_mut().deref_mut()
} }

View File

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

View File

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