Trait Map

Rust map for dynamic trait storage and references

Note: this library must be compiled on Rust Nightly. It uses the ptr_metadata and unsize features.

About

This crate allows you to dynamically search for traits inside a map. For example, assume we have some traits and structs that implement those traits:

```rust trait ExampleTrait { fn dosomething(&self) -> u32; fn doanother_thing(&mut self); }

trait ExampleTraitTwo { fn test_method(&self); }

struct MyStruct { // ... }

struct AnotherStruct { // ... }

impl ExampleTrait for MyStruct { fn dosomething(&self) -> u32 { /* Code */ } fn doanother_thing(&mut self) { /* Code */ } }

impl ExampleTrait for AnotherStruct { fn dosomething(&self) -> u32 { /* Code */ } fn doanother_thing(&mut self) { /* Code */ } }

impl ExampleTraitTwo for AnotherStruct{ fn test_method(&self) { /* Code */ } } ```

We can use TraitMap to have iterators over the dyn Trait types as follows:

```rust use trait_map::{TraitMap, TraitMapEntry, Context};

impl TraitMapEntry for MyStruct { fn oncreate<'a>(&mut self, context: Context<'a>) { // Must explicitly list which traits to expose context .downcast::() .addtrait::(); }

// Can be overridden to update the exposed traits in the map fn onupdate<'a>(&mut self, context: Context<'a>) { context .downcast::() .removetrait::(); } }

impl TraitMapEntry for AnotherStruct { fn oncreate<'a>(&mut self, context: Context<'a>) { // Must explicitly list which traits to expose context .downcast::() .addtrait::() .add_trait::(); } }

fn main() { let mut map = TraitMap::new(); map.addentry(MyStruct { /* ... */ }); map.addentry(AnotherStruct { /* ... */ });

// Can iterate over all types that implement ExampleTrait // Notice that entry is "&dyn mut ExampleTrait" for (entryid, entry) in map.getentriesmut::() { entry.doanother_thing(); }

// Can iterate over all types that implement ExampleTraitTwo // Notice that entry is "&dyn ExampleTraitTwo" for (entryid, entry) in map.getentries::() { entry.test_method(); } } ```

Deriving

If you enable the derive feature flag, you can automatically derive TraitMapEntry. You need to use one or more #[trait_map(...)] macros to specify which traits to register with the TraitMap. It uses the proc_macro_diagnostic feature to emit helpful warnings when compiling on nightly.

```rust use trait_map::TraitMapEntry;

// ...

[derive(Debug, TraitMapEntry)]

[trait_map(ExampleTrait, ExampleTraitTwo)]

[trait_map(std::fmt::Debug)]

struct DerivedStruct { // ... }

impl ExampleTrait for DerivedStruct { fn dosomething(&self) -> u32 { /* Code */ } fn doanother_thing(&mut self) { /* Code */ } }

impl ExampleTraitTwo for DerivedStruct{ fn test_method(&self) { /* Code */ } } ```