Downcast

Rust enums are great for types where all variations are known beforehand. But in the case where you want to implement a container of user-defined types, an open-ended type like a trait object is needed. In some cases, it is useful to cast the trait object back into its original concrete type to access additional functionality and performant inlined implementations.

downcast-rs adds basic downcasting support to trait objects, supporting type parameters and constraints.

To make a trait downcastable, make it extend the downcast::Downcast trait and invoke impl_downcast! on it as follows:

```rust trait Trait: Downcast {} impl_downcast!(Trait);

// or

trait TraitGeneric: Downcast {} impl_downcast!(TraitGeneric);

// or

trait TraitGenericConstrained: Downcast {} impl_downcast!(TraitGenericConstrained where T: Copy);

// or

// Use this variant when specifying concrete type parameters. trait TraitGenericConcrete: Downcast {} impl_downcast!(concrete TraitGenericConcrete); ```

Example without generics

```rust

[macro_use]

extern crate downcast; use downcast::Downcast;

// To create a trait with downcasting methods, extend Downcast and run // impldowncast!() on the trait. trait Base: Downcast {} impldowncast!(Base);

// Concrete type implementing Base. struct Foo(u32); impl Base for Foo {}

fn main() { // Create a trait object. let mut base: Box = Box::new(Foo(42));

// Downcast to Foo.
assert_eq!(base.downcast_ref::<Foo>().unwrap().0, 42);

} ```

Example with a generic trait

```rust

[macro_use]

extern crate downcastrs; use downcastrs::Downcast;

// To create a trait with downcasting methods, extend Downcast and run // impldowncast!() on the trait. trait Base: Downcast {} impldowncast!(Base); // or: impl_downcast!(concrete Base);

// Concrete type implementing Base. struct Foo(u32); impl Base for Foo {}

fn main() { // Create a trait object. let mut base: Box> = Box::new(Foo(42));

// Downcast to Foo.
assert_eq!(base.downcast_ref::<Foo>().unwrap().0, 42);

} ```

License

Copyright 2015, Ashish Myles. This software is dual-licensed under the MIT and Apache 2.0 licenses.