macro_rules! match_type {
    ($value:expr, {
        $T:ty as $pat:pat => $branch:expr,
        $($tail:tt)+
    }) => { ... };
    ($value:expr, {
        $pat:pat => $branch:expr $(,)?
    }) => { ... };
}
Expand description

Match the result of an expression against multiple concrete types.

You can write multiple match arms in the following syntax:

TYPE as name => { /* expression */ }

If the concrete type matches the given type, then the value will be cast to that type and bound to the given variable name. The expression on the right-hand side of the match is then executed and returned as the result of the entire match expression.

The name following the as keyword can be any irrefutable pattern. Like match or let expressions, you can use an underscore to prevent warnings if you don’t use the casted value, such as _value or just _.

Since it would be impossible to exhaustively list all possible types of an expression, you must include a final default match arm. The default match arm does not specify a type:

name => { /* expression */ }

The original expression will be bound to the given variable name without being casted. If you don’t care about the original value, the default arm can be:

_ => { /* expression */ }

This macro has all the same rules and restrictions around type casting as cast.

Examples

use std::fmt::Display;
use castaway::match_type;

fn to_string<T: Display + 'static>(value: T) -> String {
    match_type!(value, {
        String as s => s,
        &str as s => s.to_string(),
        s => s.to_string(),
    })
}

println!("{}", to_string("foo"));