Cast from Concrete to Any and subtraits
⚓ Rust 📅 2025-11-07 👤 surdeus 👁️ 2AnyTrait
I needed to write some almost-OOP code in rust and I needed something like ::core::any::Any, but that let me downcast to traits, without knowing the concrete type.
After reading around how it is not possible to just directly downcast for a lot of reasons, I made a small crate to do something like that (with extra steps).
docs on: any_trait - Rust
code on: GitHub - LucaFulchir/any-trait: any-trait: rust crate to downcast to any sub-trait
What it gives you
I have not actually even started using it, but I though I might get some comments here on what parts are not going to work for reasons I don't know, or some comments on how this will enable horrifying half-OOP code in your codebase from now on.
Currently it lets you:
- Upcast from the concrete type to
AnyTrait(like core'sAny) - Downcast from the
AnyTraitto the concrete type (like core'sAny) - Downcast from
AnyTraitto any other&dyn SubTraitimplemented by your concrete type (missing from core's Any) - Upcast from subtraits that require
AnyTraitto&dyn AnyTrait
I have only implemented the downcast_ref::<T> and downcast_mut::<T> for the basic case, I will have to duplicate things a bit to add Sync and Send support.
check the test directory for a working example
How it works
First we need a ::core::any::TypeId that is const-comparable, sortable.
we use ::core::any::type_name and do the rest manually since I could not find a way to use TypeId for that.
Then for every time you add #[derive(AnySubTrait)] for your structs, we add an impl AnyTrait that has a const list of the types it can be up/down cast to.
This AnyTrait has a method that will cast to the concrete to the correct subtrait....and then union to usize. horrifying, I know.
But that lets us have a common impl dyn AnyTrait implementation that can actually take that and use generics to cast back to the &dyn Trait that you requested.
Everything not marked as unsafe should be safe, and you won't need to use unsafe.
Performance
This is not a zero-cost abstraction since we need to search the correct type at runtime in a list.
Comments?
1 post - 1 participant
🏷️ Rust_feed