Suppose I have a trait object of type Asset
, which is stored in an Arc
, and I want to convert it to an Arc<dyn Any>
to facilitate later downcasting.
Is there any safe way to do this? I have tried this (unsafe) strategy using the as-any
crate, but it seems to break the type information as I can't downcast
the resulting Arc<dyn Any>
to its base type:
let res: Box<dyn Asset> = thing_that_returns_dyn_asset();
let res: Arc<dyn Asset> = Arc::from(res);
// Unsafe: Cast an Arc<dyn Asset> to an Arc<dyn Any>.
let res : Arc<dyn Any> = unsafe {
Arc::from_raw(Arc::into_raw(res).as_any())
};
But it does not seem to work. I'm aware that there's a currently experimental feature to upcast objects, but that doesn't seem to help.
The easiest way is to add a method that casts from Arc<Asset>
to Arc<dyn Any>
. Following as-any
, we can do that in a custom trait and have a blanket implementation for it:
pub trait AsAnyArc {
fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any>;
}
impl<T: 'static> AsAnyArc for T {
fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> { self }
}
pub trait Asset: AsAnyArc { ... }
let res: Box<dyn Asset> = thing_that_returns_dyn_asset();
let res: Arc<dyn Asset> = Arc::from(res);
let res: Arc<dyn Any> = res.as_any_arc();