pub unsafe trait NumericBytes: Copy {
const ELEMENT: u8;
}Expand description
Types whose little-endian in-memory form is a BEVE typed array’s payload.
The bound on everything in this crate that reinterprets memory:
Reader::read_block and Writer::write_block, which copy a whole
payload in each direction, and Reader::try_slice, which hands one back
as a slice pointing into the document without copying at all.
The crate implements it for every number BEVE can name, and for
Complex of each. It is implementable from outside for
the case those cannot cover: a scalar from a crate you do not own, whose
memory is already a payload, reached through an
adapter because the orphan rule keeps Read and
Write off it. That is the whole reason it is not sealed, and it is why
it is unsafe: nothing here is checked at a use site, and the obligations
below are the reader’s and the writer’s only grounds for reinterpreting the
bytes.
§Safety
Implementing this asserts four things about Self:
- it occupies
size_of::<Self>()initialized bytes with no padding, so reading them as bytes exposes nothing uninitialized; - every bit pattern of that size is a valid value, so bytes off the wire can become one without being checked;
- on a little-endian host those bytes are exactly what BEVE stores for one
element of
ELEMENT, in exactly that order; - one such element is
size_of::<Self>()bytes of payload, so a block ofnof them is exactlyn * size_of::<Self>()bytes.
The fourth is the one a compiler can check, and it is checked: an impl
whose declared element is a width other than its own is refused where the
block helpers are instantiated. The first three are yours to hold.
#[repr(transparent)] over a primitive satisfies all four by construction
and is the shape this expects.
Nothing here says a document holds this type. That stays a runtime test
against ELEMENT, and the helpers make the caller
do it: see Read::read_bulk.
Required Associated Constants§
Sourceconst ELEMENT: u8
const ELEMENT: u8
The header one of these carries when it stands alone, which is the header a typed array of them implies for its elements.
What a stored array’s element type is compared against, and so what decides whether its payload is already this type’s memory or has to be converted element by element. A newtype over a primitive forwards the primitive’s:
use structio::beve::NumericBytes;
#[derive(Clone, Copy)]
#[repr(transparent)]
struct Celsius(f64);
// SAFETY: `repr(transparent)` over `f64`, which satisfies all four
// clauses, and the declared element is `f64`'s own.
unsafe impl NumericBytes for Celsius {
const ELEMENT: u8 = <f64 as NumericBytes>::ELEMENT;
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".