Crate isrepr

Source
Expand description

Type conversions from arbitrary memory.

§Intro

Rust allows us to specify stable layouts of types with #[repr(C)] and friends. However, this does not allow us to cast any properly sized and aligned memory to those types, since some values may be invalid and making such a cast in Rust is immediate undefined behaviour. For APIs facing outside Rust, this is very inconvenient.

This crate provides a HasRepr trait that defines the Raw associated type. That type has the same layout as Self, but is valid for all memory contents. It also provides a method for validating that the representation can be cast to a valid value, and methods that convert by value and by reference that use this validating method.

A derive macro IsRepr can derive an implementation of HasRepr. This derivation works for most repr(C) types, as long as all their members implement HasRepr themselves. Implementations of HasRepr are provided for most primitive types.

As an extra, the module defines a simple Repr<T> wrapper which transparently wraps the underlying representation of T and is guaranteed to be a unique type for every T.

For example, a representation can be derived and used as follows:

use isrepr::{IsRepr, Repr, ReprError};
use core::convert::TryInto;
use core::mem::transmute;

#[derive(IsRepr, Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
enum Foo {
    FOO = 1,
    BAR = 3,
}

// We accept data from some "untrusted" context.
fn bar(f_repr: Repr<Foo>) -> Result<Foo, ReprError> {
    f_repr.repr_try_into()
}

fn main() {
    // Pretend that we're some untrusted context.
    let foo = bar(unsafe { transmute(Foo::FOO) }).unwrap();
    assert_eq!(foo, Foo::FOO);

    // Send an invalid value!
    bar(unsafe { transmute(17u8) }).unwrap_err();
}

§Sources

You can find Rust’s type layout guarantees here:

https://doc.rust-lang.org/reference/type-layout.html

Structs§

Repr
Type-checked underlying representation of a type.
ReprError
Error type used when conversion from underlying type fails.

Traits§

HasRepr
Trait for types that have canonical underlying representations.
RawTryInto
Helper trait for converting from the raw underlying type.

Derive Macros§

IsRepr
Automatic derivation of HasRepr.