specialized-dispatch
This crate provides a procedural macro, specialized_dispatch, a convenient
way to implement different behaviors based on type of an expression.
This works by creating different specializations in the callsite by making use
of min_specialization nightly feature under the hood.
As such, the caller needs to enable this nightly feature for the library from
which this macro is called.
Simple Example
#![feature(min_specialization)]
use specialized_dispatch::specialized_dispatch;
fn example<Arg>(arg: Arg) -> String {
specialized_dispatch!(
arg,
Arg -> String,
fn <T>(_: T) => format!("default value"),
fn (v: u8) => format!("u8: {}", v),
fn (v: u16) => format!("u16: {}", v),
)
}
assert_eq!(example(1.0), "default value");
assert_eq!(example(5u8), "u8: 5");
assert_eq!(example(10u16), "u16: 10");
example function roughly expands to below code. Note that exact expansion is internal
implementation detail. This example is provided to demonstrate how it works under the
hood.
fn example<T>(t: T) -> String {
trait SpecializedDispatchCall<T> {
fn dispatch(t: T) -> String;
}
impl<T> SpecializedDispatchCall<T> for T {
default fn dispatch(_: T) -> String {
format!("default value")
}
}
impl SpecializedDispatchCall<u8> for u8 {
fn dispatch(v: u8) -> String {
format!("u8: {}", v)
}
}
impl SpecializedDispatchCall<u8> for u16 {
fn dispatch(v: u16) -> String {
format!("u16: {}", v)
}
}
<Arg as SpecializedDispatchCall<Arg>>::dispatch(arg)
}