RPC: Functionality to downcast dyn Object to a dyn Trait.
This is a rather tricky piece of functionality. It works as follows.
We introduce a CastTable
type. Each CastTable
tells us how to
downcast dyn Object
for objects of a single concrete type.
The Object
type now has a get_casttable
method that returns
an empty CastTable
by default.
CastTable
is, internally, a map from the TypeId
of the target
dyn Trait reference type to a function
fn(&dyn Object) -> &dyn Trait
. These functions are stored as
Box<dyn Any + ...>
. (They are Boxed because they may refer to
generic functions, which you can't get a static reference to,
and they're Any because the functions have different types.)
The decl_object!
macro now implements get_casttable
as
appropriate. (The syntax is a bit janky, but that's what we get
for not using derive_adhoc.) For non-generic types, get_casttable
uses a Lazy<CastTable>
. to initialize a CastTable exactly once.
For generic types, it use a Lazy<RwLock<HashMap<..>>
to
build one CastTable per instantiation of the generic type.
This could probably be optimized a bit more, the yaks could be
shaved in a more scintillating hairstyle, and the syntax for
generic decl_object
could definitely be improved.