Crate safe_transmute[][src]

Expand description

This crate contains checked implementations of transmutation procedures, some of which ensure memory safety.

Crate outline

The following modules are available:

  • The functions in the base module are not inherently safe, but just protected against out of boundary access (like trying to create an 8-byte type from 7 bytes). These functions are as safe as the data passed to them: any attempt of transmuting data to an invalid memory representation is still undefined behavior. Moreover, unaligned memory access is not prevented, and must be previously ensured by the caller.
  • The guard module contains the Guard API, which imposes slice boundary restrictions in a conversion.
  • The trivial module introduces the TriviallyTransmutable trait, which statically ensures that any bit combination makes a valid value for a given type. The functions in this module are safer than base, but still do not prevent unaligned memory access.
  • to_bytes enables the opposite operation of reintepreting values as bytes.
  • The bool module ensures safe transmutation of bytes to boolean values.
  • At the root of this crate, there are transmutation functions with enough checks to be considered safe to use in any circumstance. The operation may still arbitrarily return (recoverable) errors due to unaligned data or incompatible vector transmutation targets, but it will not eat your laundry, and helper functions are available to assist the programmer in making some use cases work.

This crate can be used in a no-std environment by disabling the std feature through specifying default-features = false on import. However, std is only used for integration with std::error::Error.

Note, though, that functions operating on items from alloc will also be disabled by this. If your no-std environment has an alloc implementation, you will have to reenable them by using features = ["alloc"].

Migrating

If you’ve used safe-transmute before v0.11, we recommend the v0.11 migration guide to help get you going quickly.

Examples

View bytes as a series of u16s, with a single-many boundary guard (at least one value, extraneous bytes are allowed):

let bytes = &[0x00, 0x01, 0x12, 0x24,
              0x00]; // 1 spare byte
match transmute_many::<u16, SingleManyGuard>(bytes) {
    Ok(words) => {
        assert_eq!(words,
                   [u16::from_be(0x0001), u16::from_be(0x1224)]);
    },
    Err(Error::Unaligned(e)) => {
        // Copy needed, would otherwise trap on some archs
        let words = e.copy();
        assert_eq!(*words,
                   [u16::from_be(0x0001), u16::from_be(0x1224)]);
    },
    Err(e) => panic!("Unexpected error: {}", e),
}

Since one may not always be able to ensure that a slice of bytes is well aligned for reading data of different constraints, such as from u8 to u16, the operation may fail without a trivial way of preventing it.

As a remedy, the data can instead be copied byte-for-byte to a new vector, with the help of the try_copy!() macro.

let bytes = &[0x00, 0x01, 0x12, 0x24, 0x00];
let words = try_copy!(transmute_many::<u16, SingleManyGuard>(bytes));

assert_eq!(*words,
           [u16::from_be(0x0001), u16::from_be(0x1224)]);

View all bytes as a series of u16s:

// Assuming little-endian
let bytes = &[0x00, 0x01, 0x12, 0x34];
let words = try_copy!(transmute_many_pedantic::<u16>(bytes));

assert_eq!(*words, [0x0100, 0x3412]);

View a byte slice as a single f64:

assert_eq!(transmute_one::<f64>(
   &[0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x40])?,
   2.0);

View a series of u16s as bytes:

assert_eq!(transmute_to_bytes(&[0x0001u16,
                                0x1234u16]),
           &[0x01, 0x00, 0x34, 0x12]);

Re-exports

pub use self::guard::SingleValueGuard;
pub use self::guard::PermissiveGuard;
pub use self::guard::SingleManyGuard;
pub use self::guard::PedanticGuard;
pub use self::guard::Guard;
pub use self::error::UnalignedError;
pub use self::error::ErrorReason;
pub use self::error::GuardError;
pub use self::error::Error;
pub use self::error::IncompatibleVecTargetError;
pub use self::trivial::TriviallyTransmutable;
pub use self::trivial::align_to_mut;
pub use self::trivial::align_to;
pub use self::to_bytes::transmute_one_to_bytes_mut;
pub use self::to_bytes::transmute_one_to_bytes;
pub use self::to_bytes::transmute_to_bytes_mut;
pub use self::to_bytes::transmute_to_bytes;
pub use self::to_bytes::transmute_to_bytes_vec;
pub use self::bool::transmute_bool_vec_permissive;
pub use self::bool::transmute_bool_vec_pedantic;
pub use self::bool::transmute_bool_permissive;
pub use self::bool::transmute_bool_pedantic;

Modules

align

Alignment checking primitives.

base

Primitives for object and array transmutation.

bool

Functions for safe transmutation to bool.

error

Detectable and recoverable-from transmutation precondition errors.

guard

The guard module exposes an API for memory boundary checking.

migration

Migration guides.

to_bytes

Functions for transmutation from a concrete type to bytes.

trivial

Transmutation of trivial objects

util

Module containing various utility functions.

Macros

try_copy

Retrieve the result of a transmutation, copying the data if it could not be safely performed due to memory alignment constraints.

try_copy_unchecked

Retrieve the result of a non-trivial transmutation, copying the data if it could not be safely performed due to memory alignment constraints.

Functions

transmute_many

Transmute a byte slice into a sequence of values of the given type.

transmute_many_mut

Transmute a mutable byte slice into a mutable sequence of values of the given type.

transmute_many_pedantic

Transmute a byte slice into a sequence of values of the given type.

transmute_many_pedantic_mut

Transmute a byte slice into a sequence of values of the given type.

transmute_many_permissive

Transmute a byte slice into a sequence of values of the given type.

transmute_many_permissive_mut

Transmute a byte slice into a sequence of values of the given type.

transmute_one

Transmute a byte slice into a single instance of a trivially transmutable type.

transmute_one_pedantic

Transmute a byte slice into a single instance of a trivially transmutable type.

transmute_vec

Transform a vector into a vector of values with the given target type.