Crates.io | trait_cast_rs |
lib.rs | trait_cast_rs |
version | |
source | src |
created_at | 2022-08-28 16:45:22.536321 |
updated_at | 2024-12-12 20:23:34.144838 |
description | Get your own Any with support for casting to trait objects. |
homepage | https://github.com/ink-feather-org/trait_cast_rs |
repository | https://github.com/ink-feather-org/trait_cast_rs |
max_upload_size | |
id | 653973 |
Cargo.toml error: | TOML parse error at line 21, column 1 | 21 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
This crate requires a nightly compiler.
This crate adds the TraitcastableAny
replacement trait for Any
.
It closely resembles the Any
trait for downcasting to a concrete type.
Additionally the TraitcastableAny
trait allows you to directly downcast to other &dyn Trait
s.
To make this work you must specify all target traits you want to be able to downcast to in the make_trait_castable(Trait1, Trait2, ...)
attribute macro.
This macro can be applied to structs, enums and unions.
It implements the TraitcastableAny
trait for your struct, enum or union.
Note: No modifications on the target traits are necessary. Which allows you to downcast to traits of other libraries you don't control.
Add the trait_cast_rs
crate to your Cargo.toml
and switch to a nightly compiler.
Add the #[make_trait_castable(Trait1, Trait2, ...)]
macro to your struct/enum/union.
List all traits you eventually want to be able to downcast
to.
You must implement all listed traits.
Use references to dyn TraitcastableAny
throughout your code instead of dyn Any
.
Enjoy downcasting to trait objects.
#![cfg_attr(feature = "min_specialization", feature(min_specialization))]
#![feature(ptr_metadata)]
use trait_cast_rs::{
make_trait_castable, TraitcastableAny, TraitcastableAnyInfra, TraitcastableAnyInfraExt,
};
#[make_trait_castable(Print)]
struct Source(i32);
trait Print {
fn print(&self);
}
impl Print for Source {
fn print(&self) {
println!("{}", self.0);
}
}
let source = Box::new(Source(5));
let castable: Box<dyn TraitcastableAny> = source;
let x: &dyn Print = castable.downcast_ref().unwrap();
x.print();
Check out the examples.
If you want to do something the make_trait_castable
attribute macro can't handle (like implementing for generic structs - pull requests are welcome)
check out the manual*.rs
examples.
There is also a decl marco available - check out the with_decl_macro*.rs
examples.
alloc
- Adds special implementations for Box
, Rc
and Arc
. Default feature.
min_specialization
-
Implements TraitcastableAny
for 'static
types.
Even types you don't control.
However these default implementations of TraitcastableAny
have no downcast targets.
It additionally requires the following feature flags in the user code:
#![feature(min_specialization)]
downcast_unchecked
- Adds *_unchecked
variants to the downcast functions.
Any
With the trait_upcasting
rust feature you can even cast any &dyn TraitcastableAny
to &dyn Any
.
Alternatively you can list the Any
trait as a traitcast target.
However it is not possible to cast back to TraitcastableAny
(pull requests are welcome).
raldone01 and onestacked are the primary authors and maintainers of this library.
This project is released under either:
at your choosing.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
I will give you a quick rundown of our internal operations: 💦
Compile time:
Add a casting
function for every downcast path to the concrete type.
This function gets a dyn TraitcastableAny
, which it then downcasts to a concrete type using Any
in the background.
In the last step it casts the concrete type to the wanted trait object and returns it.
Add a traitcast_targets
function that returns a const slice of (typeid
, transmuted casting function ptr).
Runtime:
typeid
downcast
function all use unsafe - expectedly.105%
save. TypeId
s don't collide.This alternatives section is not exhaustive for a more objective/detailed comparison see the alternatives section of cast_trait_object.
lazy_static
.
To be fair it allows you to use the default Any
and doesn't require nightly.TODO: Remove this section once our last update is 6 years old.