# enum_downcast
[](https://github.com/ryo33/enum_downcast)

[](https://crates.io/crates/enum_downcast)
[](https://docs.rs/enum_downcast)
Safe downcasting for enums
## Example
```rust
#[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](https://github.com/ryo33/enum_downcast/tree/main/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
## Features
- completely `#![no_std]`
- no unsafe code (like `std::mem::transmute`)
- no dynamic dispatch
- `#[enum_downcast(skip)]` to skip some variants (especially not downcastable
ones)
- enums with type parameters (see
[example](https://github.com/ryo33/enum_downcast/tree/main/examples/generics.rs))
- custom downcast implementation without derive macro (see
[example](https://github.com/ryo33/enum_downcast/tree/main/examples/custom_impl.rs))
- partial custom downcast implementation for some variants with
`#[enum_downcast(skip)]` (see
[example](https://github.com/ryo33/enum_downcast/tree/main/examples/partial_custom_impl.rs))
- compatible with other macros, such as `serde`, `strum`, and `enum_dispatch`
(see
[example with serde and strum](https://github.com/ryo33/enum_downcast/tree/main/examples/other_derives.rs)
and
[example with enum_dispatch](https://github.com/ryo33/enum_downcast/tree/main/examples/enum_dispatch.rs))
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](https://github.com/rust-lang/rust/issues/31844) in stable Rust.
You can workaround this by using nightly compiler with `min_specialization`
feature like
[this example](https://github.com/ryo33/enum_downcast/tree/main/examples/specialization.rs).
As of specialization stabilized in the future, this limitation will be cleared,
and you don't need any boilerplate code like the example.