Skip to main content

NumericBytes

Trait NumericBytes 

Source
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 of n of them is exactly n * 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§

Source

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".

Implementations on Foreign Types§

Source§

impl NumericBytes for f32

Source§

impl NumericBytes for f64

Source§

impl NumericBytes for i8

Source§

impl NumericBytes for i16

Source§

impl NumericBytes for i32

Source§

impl NumericBytes for i64

Source§

impl NumericBytes for i128

Source§

impl NumericBytes for isize

Source§

impl NumericBytes for u8

Source§

impl NumericBytes for u16

Source§

impl NumericBytes for u32

Source§

impl NumericBytes for u64

Source§

impl NumericBytes for u128

Source§

impl NumericBytes for usize

Implementors§