Crate safe_transmute[−][src]
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 theTriviallyTransmutable
trait, which statically ensures that any bit combination makes a valid value for a given type. The functions in this module are safer thanbase
, 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 u16
s, 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 u16
s:
// 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 u16
s 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 |
error | Detectable and recoverable-from transmutation precondition errors. |
guard | The |
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. |