A key/value data structure keyed by Trait?


#1

Hey everyone. I’m a Rust beginner, but am already contributing to the community: daringordon.com/rust_tutorials/

I’m interested in reproducing a “service registry” design pattern in Rust where by a key/value registry contains “services”, each that implements a uniquely identifiable Trait. The intent here is to allow modules from anywhere in an application to look up and borrow a service to accomplish a task, without knowing the concrete implementation but rather only the Trait (contract) that is implemented.

One example of this in the wild is within the Pyramid Web framework (Python), which makes extensive use of the zope component architecture (and consequently zope interfaces).

How would you approach this design and would you consider this design pattern rustic?


#2

It sounds like a very dynamic thing, where you can store and get objects of any type, so it’s probably not very “rustic” approach in general.

It might be doable with a help of TypeId as the hash key, and Any to cast values back to their original specific types.

It might be useful to know that Box<Trait> (Trait Object) is a special construct that uses traits via dynamic dispatch, so it’s much more flexible than trying to use generics.

But I think another approach might be better, e.g. dependency injection. Or the registry, instead of supporting arbitrary key-value storage, having a fixed set of concrete getter functions for specific types.


#3

What if instead we knew the traits that will be implemented. How would we key then?


#4

I assume you want something like:

let database = registry.get::<DatabaseTrait>();

I wrote code for this in another topic:


#5

At first read, I think so!


#6

Check typemap crate.


#7

https://crates.io/crates/typemap


#8

Thanks – will do.


#9

Excellent :slight_smile: