Crates.io | enum_downcast |
lib.rs | enum_downcast |
version | 0.2.0 |
source | src |
created_at | 2023-12-30 09:49:20.197553 |
updated_at | 2024-06-16 01:39:48.95937 |
description | Safe downcasting for enums |
homepage | |
repository | https://github.com/ryo33/enum_downcast |
max_upload_size | |
id | 1084064 |
size | 11,294 |
Safe downcasting for enums
#[derive(EnumDowncast)]
enum Enum {
Player(Player),
Enemy(Enemy),
Items { vec: Vec<Item> }, // derived code will be identical to if it were `Items(Vec<Items>)`
#[enum_downcast(skip)]
Other,
}
let container = Enum::Player(Player { name: "Ryo".to_string() });
let _player_ref: &Player = container.downcast_ref::<Player>().unwrap();
let _player_mut: &mut Player = container.downcast_mut::<Player>().unwrap();
let player: Player = container.downcast::<Player>().unwrap();
You need derive
feature to use the derive macro.
You can see more examples in /examples.
My favorite one is one about custom downcast that allows interesting behavior like: https://github.com/ryo33/enum_downcast/blob/75adcbc8d24adb4e9d7b3c873e92bfff0dde7882/examples/partial_custom_impl.rs#L44-L53
#![no_std]
std::mem::transmute
)#[enum_downcast(skip)]
to skip some variants (especially not downcastable
ones)#[enum_downcast(skip)]
(see
example)serde
, strum
, and enum_dispatch
(see
example with serde and strum
and
example with enum_dispatch)There is one limitation: you cannot compile a code that downcasts an enum to any
type not listed in the enum definition, because of the lack of the
specialization in stable Rust.
You can workaround this by using nightly compiler with min_specialization
feature like
this example.
As of specialization stabilized in the future, this limitation will be cleared,
and you don't need any boilerplate code like the example.