Cast from dyn Any to other trait objects
no_stdno alloc support- No proc macros
- No unsafe code
Usage
[]
= "0.1"
Then use the register!{ Type => Trait } declarative macro and the [Cast] traits.
For embedded, the linker needs to be informed of the type registry.
Example
use Any;
use ;
// Some example traits to play with
use ;
// Add types and trait implementations to the default registry
// Implementation status is verified at compile time
register!
// Registering foreign types and traits works fine
// Serialization/deserialization of `dyn Any` is a major use case
// register! { i32 => dyn erased_serde::Serialize }
// If a type is not Send + Sync, it can't cast as Arc.
// `no_arc` accounts for that
register!
// Check for trait impl registration on concrete type
assert!;
// Check for trait impl registration on Any
let any: &dyn Any = &42i32;
assert!;
// SubAssign<i32> is impl'd for i32 but not registered
assert!;
// Cast ref
let a: &dyn Debug = any.cast.unwrap;
println!;
// Cast mut
let mut value = 5i32;
let any: &mut dyn Any = &mut value;
let v: &mut dyn = any.cast.unwrap;
*v += 3;
assert_eq!;
// Cast Box
let any: = Boxnew;
let _: = any.cast.unwrap;
// Cast Rc
use Rc;
let any: = new;
let _: = any.cast.unwrap;
// Cast Arc
use Arc;
let any: = new;
let _: = any.cast.unwrap;
// Explicit registry usage
let any: &dyn Any = &0i32;
let _: &dyn Debug = REGISTRY.cast_ref.unwrap;
// Custom non-static registry
let myreg = new;
let _: &dyn Debug = myreg.cast_ref.unwrap;
// Autotraits and type/const generics are distinct
let a: = any.cast;
assert!;
// Registration in the default registry can happen anywhere
// in any order in any downstream crate
register!
Related crates
intertrait: source of ideas forcrosstrait, similar goals, similar features,std, proc macrosminiconf: provides several ways to getdyn Anyfrom nodes in heterogeneous nested data structures,no_std, no allocerased_serde:Serialize/Serializer/Deserializertrait objectsdowncast/downcast-rs: supportdyn Trait -> Typelinkme: linker magic used here to build distributed static type registry
Limitations
Registry size on no_std
Currently the size of the global registry on no_std is fixed and arbitrarily set to 128 entries.
Auto traits
Since adding any combination of auto traits (in particular Send, Sync, Unpin) to a trait results in a distinct trait,
all relevant combinations of traits plus auto traits needs to be registered explicitly.
Global registry
A custom non-static [Registry] can be built and used explicitly but the Cast traits will not use it.
used_linker
The unstable used_with_arg feature may be required to keep the linker from optimizing away the items in the registry.
Enable it using the used_linker crate feature and use a nightly toolchain.
Registry keys
The registry keys are size_of::<[TypeId; 2]>() = 32 bytes large.
Hashing and key storage/comparison is not tuned for performance.