pub enum ConvertError<A, S, V> {
Alignment(A),
Size(S),
Validity(V),
}
Expand description
Zerocopy’s generic error type.
Generally speaking, zerocopy’s conversions may fail for one of up to three reasons:
AlignmentError
: the conversion source was improperly alignedSizeError
: the conversion source was of incorrect sizeValidityError
: the conversion source contained invalid data
However, not all conversions produce all errors. For instance,
FromBytes::ref_from_bytes
may fail due to alignment or size issues, but
not validity issues. This generic error type captures these
(im)possibilities via parameterization: A
is parameterized with
AlignmentError
, S
is parameterized with SizeError
, and V
is
parameterized with Infallible
.
Zerocopy never uses this type directly in its API. Rather, we provide three pre-parameterized aliases:
CastError
: the error type of reference conversionsTryCastError
: the error type of fallible reference conversionsTryReadError
: the error type of fallible read conversions
Variants§
Alignment(A)
The conversion source was improperly aligned.
Size(S)
The conversion source was of incorrect size.
Validity(V)
The conversion source contained invalid data.
Implementations§
Source§impl<Src, Dst: ?Sized> ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, Infallible>
impl<Src, Dst: ?Sized> ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, Infallible>
Sourcepub fn map_src<NewSrc>(
self,
f: impl FnOnce(Src) -> NewSrc,
) -> CastError<NewSrc, Dst>
pub fn map_src<NewSrc>( self, f: impl FnOnce(Src) -> NewSrc, ) -> CastError<NewSrc, Dst>
Maps the source value associated with the conversion error.
This can help mitigate issues with Send
, Sync
and 'static
bounds.
§Examples
use zerocopy::*;
let source: [u8; 3] = [0, 1, 2];
// Try to read a `u32` from `source`. This will fail because there are insufficient
// bytes in `source`.
let maybe_u32: Result<&u32, CastError<&[u8], u32>> = u32::ref_from_bytes(&source[..]);
// Map the error's source to its size and address.
let maybe_u32: Result<&u32, CastError<(usize, usize), u32>> = maybe_u32.map_err(|err| {
err.map_src(|src| (src.len(), src.as_ptr() as usize))
});
Source§impl<Src, Dst: ?Sized + TryFromBytes> ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, ValidityError<Src, Dst>>
impl<Src, Dst: ?Sized + TryFromBytes> ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, ValidityError<Src, Dst>>
Sourcepub fn map_src<NewSrc>(
self,
f: impl FnOnce(Src) -> NewSrc,
) -> TryCastError<NewSrc, Dst>
pub fn map_src<NewSrc>( self, f: impl FnOnce(Src) -> NewSrc, ) -> TryCastError<NewSrc, Dst>
Maps the source value associated with the conversion error.
This can help mitigate issues with Send
, Sync
and 'static
bounds.
§Examples
use core::num::NonZeroU32;
use zerocopy::*;
let source: [u8; 3] = [0, 0, 0];
// Try to read a `NonZeroU32` from `source`.
let maybe_u32: Result<&NonZeroU32, TryCastError<&[u8], NonZeroU32>>
= NonZeroU32::try_ref_from_bytes(&source[..]);
// Map the error's source to its size and address.
let maybe_u32: Result<&NonZeroU32, TryCastError<(usize, usize), NonZeroU32>> =
maybe_u32.map_err(|err| {
err.map_src(|src| (src.len(), src.as_ptr() as usize))
});
Source§impl<Src, Dst: ?Sized + TryFromBytes> ConvertError<Infallible, SizeError<Src, Dst>, ValidityError<Src, Dst>>
impl<Src, Dst: ?Sized + TryFromBytes> ConvertError<Infallible, SizeError<Src, Dst>, ValidityError<Src, Dst>>
Sourcepub fn map_src<NewSrc>(
self,
f: impl FnOnce(Src) -> NewSrc,
) -> TryReadError<NewSrc, Dst>
pub fn map_src<NewSrc>( self, f: impl FnOnce(Src) -> NewSrc, ) -> TryReadError<NewSrc, Dst>
Maps the source value associated with the conversion error.
This can help mitigate issues with Send
, Sync
and 'static
bounds.
§Examples
use core::num::NonZeroU32;
use zerocopy::*;
let source: [u8; 3] = [0, 0, 0];
// Try to read a `NonZeroU32` from `source`.
let maybe_u32: Result<NonZeroU32, TryReadError<&[u8], NonZeroU32>>
= NonZeroU32::try_read_from_bytes(&source[..]);
// Map the error's source to its size.
let maybe_u32: Result<NonZeroU32, TryReadError<usize, NonZeroU32>> =
maybe_u32.map_err(|err| {
err.map_src(|src| src.len())
});
Trait Implementations§
Source§impl<A: Display, S: Display, V: Display> Display for ConvertError<A, S, V>
impl<A: Display, S: Display, V: Display> Display for ConvertError<A, S, V>
Produces a human-readable error message.
The message differs between debug and release builds. When
debug_assertions
are enabled, this message is verbose and includes
potentially sensitive information.
Source§impl<A, S, V> Error for ConvertError<A, S, V>
impl<A, S, V> Error for ConvertError<A, S, V>
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
Source§impl<Src, Dst: ?Sized, S, V> From<AlignmentError<Src, Dst>> for ConvertError<AlignmentError<Src, Dst>, S, V>
impl<Src, Dst: ?Sized, S, V> From<AlignmentError<Src, Dst>> for ConvertError<AlignmentError<Src, Dst>, S, V>
Source§fn from(err: AlignmentError<Src, Dst>) -> Self
fn from(err: AlignmentError<Src, Dst>) -> Self
Source§impl<Src, Dst: ?Sized + Unaligned, S, V> From<ConvertError<AlignmentError<Src, Dst>, S, V>> for ConvertError<Infallible, S, V>
impl<Src, Dst: ?Sized + Unaligned, S, V> From<ConvertError<AlignmentError<Src, Dst>, S, V>> for ConvertError<Infallible, S, V>
Source§fn from(
err: ConvertError<AlignmentError<Src, Dst>, S, V>,
) -> ConvertError<Infallible, S, V>
fn from( err: ConvertError<AlignmentError<Src, Dst>, S, V>, ) -> ConvertError<Infallible, S, V>
Infallibly discards the alignment error from this ConvertError
since
Dst
is unaligned.
Since Dst: Unaligned
, it is impossible to encounter an alignment
error. This method permits discarding that alignment error infallibly
and replacing it with Infallible
.
§Examples
use core::convert::Infallible;
use zerocopy::*;
#[derive(TryFromBytes, KnownLayout, Unaligned, Immutable)]
#[repr(C, packed)]
struct Bools {
one: bool,
two: bool,
many: [bool],
}
impl Bools {
fn parse(bytes: &[u8]) -> Result<&Bools, AlignedTryCastError<&[u8], Bools>> {
// Since `Bools: Unaligned`, we can infallibly discard
// the alignment error.
Bools::try_ref_from_bytes(bytes).map_err(Into::into)
}
}
Source§impl<Src, Dst: ?Sized + TryFromBytes> From<ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, Infallible>> for TryCastError<Src, Dst>
impl<Src, Dst: ?Sized + TryFromBytes> From<ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, Infallible>> for TryCastError<Src, Dst>
Source§impl<Src, Dst: ?Sized + Unaligned> From<ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, Infallible>> for SizeError<Src, Dst>
impl<Src, Dst: ?Sized + Unaligned> From<ConvertError<AlignmentError<Src, Dst>, SizeError<Src, Dst>, Infallible>> for SizeError<Src, Dst>
Source§fn from(err: CastError<Src, Dst>) -> SizeError<Src, Dst>
fn from(err: CastError<Src, Dst>) -> SizeError<Src, Dst>
Infallibly extracts the SizeError
from this CastError
since Dst
is unaligned.
Since Dst: Unaligned
, it is impossible to encounter an alignment
error, and so the only error that can be encountered at runtime is a
SizeError
. This method permits extracting that SizeError
infallibly.
§Examples
use zerocopy::*;
#[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
#[repr(C)]
struct UdpHeader {
src_port: [u8; 2],
dst_port: [u8; 2],
length: [u8; 2],
checksum: [u8; 2],
}
#[derive(FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
#[repr(C, packed)]
struct UdpPacket {
header: UdpHeader,
body: [u8],
}
impl UdpPacket {
pub fn parse(bytes: &[u8]) -> Result<&UdpPacket, SizeError<&[u8], UdpPacket>> {
// Since `UdpPacket: Unaligned`, we can map the `CastError` to a `SizeError`.
UdpPacket::ref_from_bytes(bytes).map_err(Into::into)
}
}