3个版本
0.1.2 | 2023年2月17日 |
---|---|
0.1.1 | 2023年2月17日 |
0.1.0 | 2023年2月17日 |
#28 在 #downcast
用于 trait-map
19KB
149 行
特质映射
Rust动态特质存储和引用的映射
注意:此库必须在Rust Nightly上编译。它使用了ptr_metadata
和unsize
特性。
关于
这个包允许你在映射中动态搜索特质。例如,假设我们有一些特质和实现了这些特质的结构体
trait ExampleTrait {
fn do_something(&self) -> u32;
fn do_another_thing(&mut self);
}
trait ExampleTraitTwo {
fn test_method(&self);
}
struct MyStruct {
// ...
}
struct AnotherStruct {
// ...
}
impl ExampleTrait for MyStruct {
fn do_something(&self) -> u32 { /* Code */ }
fn do_another_thing(&mut self) { /* Code */ }
}
impl ExampleTrait for AnotherStruct {
fn do_something(&self) -> u32 { /* Code */ }
fn do_another_thing(&mut self) { /* Code */ }
}
impl ExampleTraitTwo for AnotherStruct{
fn test_method(&self) { /* Code */ }
}
我们可以使用TraitMap
来对dyn Trait
类型进行迭代,如下所示
use trait_map::{TraitMap, TraitMapEntry, Context};
impl TraitMapEntry for MyStruct {
fn on_create<'a>(&mut self, context: Context<'a>) {
// Must explicitly list which traits to expose
context
.downcast::<Self>()
.add_trait::<dyn ExampleTrait>();
}
// Can be overridden to update the exposed traits in the map
fn on_update<'a>(&mut self, context: Context<'a>) {
context
.downcast::<Self>()
.remove_trait::<dyn ExampleTrait>();
}
}
impl TraitMapEntry for AnotherStruct {
fn on_create<'a>(&mut self, context: Context<'a>) {
// Must explicitly list which traits to expose
context
.downcast::<Self>()
.add_trait::<dyn ExampleTrait>()
.add_trait::<dyn ExampleTraitTwo>();
}
}
fn main() {
let mut map = TraitMap::new();
map.add_entry(MyStruct { /* ... */ });
map.add_entry(AnotherStruct { /* ... */ });
// Can iterate over all types that implement ExampleTrait
// Notice that entry is "&dyn mut ExampleTrait"
for (entry_id, entry) in map.get_entries_mut::<dyn ExampleTrait>() {
entry.do_another_thing();
}
// Can iterate over all types that implement ExampleTraitTwo
// Notice that entry is "&dyn ExampleTraitTwo"
for (entry_id, entry) in map.get_entries::<dyn ExampleTraitTwo>() {
entry.test_method();
}
}
派生
如果你启用了derive
功能标志,你可以自动派生TraitMapEntry
。你需要使用一个或多个#[trait_map(...)]
宏来指定要注册到TraitMap的特质。它使用proc_macro_diagnostic
特性在Nightly编译时发出有用的警告。
use trait_map::TraitMapEntry;
// ...
#[derive(Debug, TraitMapEntry)]
#[trait_map(ExampleTrait, ExampleTraitTwo)]
#[trait_map(std::fmt::Debug)]
struct DerivedStruct {
// ...
}
impl ExampleTrait for DerivedStruct {
fn do_something(&self) -> u32 { /* Code */ }
fn do_another_thing(&mut self) { /* Code */ }
}
impl ExampleTraitTwo for DerivedStruct{
fn test_method(&self) { /* Code */ }
}
依赖
~1.5MB
~36K SLoC