Cast from Concrete to Any and subtraits

⚓ Rust    📅 2025-11-07    👤 surdeus    👁️ 2      

surdeus

AnyTrait

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's Any)
  • Downcast from the AnyTrait to the concrete type (like core's Any)
  • Downcast from AnyTrait to any other &dyn SubTrait implemented by your concrete type (missing from core's Any)
  • Upcast from subtraits that require AnyTrait to &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

Read full topic

🏷️ Rust_feed