Crate cismute

Source
Expand description

Provides safe trivial transmutes in generic context, emulating specialization on stable Rust. These functions are designed for being optimized out by the compiler, so are probably zero-cost in most cases.

fn specialized_function<T: 'static>(x: T) -> String {
    // We have an efficient algorithm for `i32` and worse algorithm for any other type.
    // With `cismute` we can do:
    match cismute::owned::<T, i32>(x) {
        Ok(x) => format!("got an i32: {x}"),
        Err(x) => format!("got something else"),
    }
}

assert_eq!(specialized_function(42_i32), "got an i32: 42");
assert_eq!(specialized_function(":)"), "got something else");

cismute::owned works only for 'static types. If your type is a reference, you should use cismute::reference or cismute::mutable.

fn specialized_function<T: 'static>(x: &T) -> String {
    // We have an efficient algorithm for `i32` and worse algorithm for any other type.
    // With `cismute` we can do:
    match cismute::reference::<T, i32>(x) {
        Ok(x) => format!("got an i32: {x}"),
        Err(x) => format!("got something else"),
    }
}

assert_eq!(specialized_function(&42_i32), "got an i32: 42");
assert_eq!(specialized_function(&":)"), "got something else");

There’s also a more generic function cismute::value which can do all three. Writing all type arguments can be cumbersome, so you can also pass the type pair as an argument via cismute::value_with:

use cismute::Pair;

fn specialized_function<T: 'static>(x: &T) -> String {
    match cismute::value_with(Pair::<(T, i32)>, x) {
        Ok(x) => format!("got an i32: {x}"),
        Err(x) => format!("got something else"),
    }
}

assert_eq!(specialized_function(&42_i32), "got an i32: 42");
assert_eq!(specialized_function(&":)"), "got something else");

There are also switch!() macro and switch() function to match one value with multiple types.

Macros§

switch
Try to match a value with any number of types. This macro does not require the switch feature.

Structs§

Pair
Pair of two types for passing to cismute::value_with.

Traits§

Cismutable
A reference that can be safely transmuted if underlying type is the same.

Functions§

from
Helper function for switch().
mutable
Transmutes a mutable reference to type T to &mut U if they are the same type. Returns the passed value back if failed.
owned
Transmutes an owned value of type T to type U if they are the same type. Returns the passed value back if failed.
reference
Transmutes reference to type T to &U if they are the same type. Returns the passed value back if failed.
switch
Try to match T with several (up to 32) other types. This function requires the switch feature, as it increases build time considerably.
value
Cismutes T or a (possibly mutable) reference to T to U with the same ownership, i.e. owned value is cismuted like with cismute::owned, reference is cismuted to reference and mutable reference is cismuted to mutable reference, if they are the same type. Returns the passed value back if failed.
value_with
Cismutes T or a (possibly mutable) reference to T to the type specified by the first argument while preserving ownership, i.e. owned value is cismuted like with cismute::owned, reference is cismuted to reference and mutable reference is cismuted to mutable reference. Returns the passed value back if failed.