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

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

Traits

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

Derive Macros