graft_core/
zerocopy_ext.rs

1use thiserror::Error;
2use zerocopy::{
3    ConvertError, Immutable, KnownLayout, SizeError, TryFromBytes, Unaligned, ValidityError,
4};
5
6pub trait TryFromBytesExt: TryFromBytes {
7    #[must_use = "has no side effects"]
8    #[inline]
9    fn try_ref_from_unaligned_bytes(source: &[u8]) -> Result<&Self, ZerocopyErr>
10    where
11        Self: Unaligned + Immutable + KnownLayout,
12    {
13        #[allow(clippy::disallowed_methods)]
14        Self::try_ref_from_bytes(source).map_err(Into::into)
15    }
16}
17
18impl<T: TryFromBytes + ?Sized> TryFromBytesExt for T {}
19
20#[derive(Debug, Error, PartialEq, Eq)]
21pub enum ZerocopyErr {
22    #[error("Invalid Alignment")]
23    InvalidAlignment,
24
25    #[error("Invalid Size")]
26    InvalidSize,
27
28    #[error("Invalid Data")]
29    InvalidData,
30}
31
32impl<A, S, V> From<ConvertError<A, S, V>> for ZerocopyErr {
33    #[inline]
34    #[track_caller]
35    fn from(value: ConvertError<A, S, V>) -> Self {
36        match value {
37            ConvertError::Alignment(_) => Self::InvalidAlignment,
38            ConvertError::Size(_) => Self::InvalidSize,
39            ConvertError::Validity(_) => Self::InvalidData,
40        }
41    }
42}
43
44impl<A, B: ?Sized> From<SizeError<A, B>> for ZerocopyErr {
45    #[inline]
46    #[track_caller]
47    fn from(_: SizeError<A, B>) -> Self {
48        Self::InvalidSize
49    }
50}
51
52impl<A, B: ?Sized + TryFromBytes> From<ValidityError<A, B>> for ZerocopyErr {
53    #[inline]
54    #[track_caller]
55    fn from(_: ValidityError<A, B>) -> Self {
56        Self::InvalidData
57    }
58}