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, associated types, 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
// or
trait TraitGenericConstrained
// or
trait TraitGenericAssociatedConstrained
// or
// Use these variants when specifying concrete type parameters.
trait TraitGenericConcrete
trait TraitGenericAssociatedConcrete
```rust
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);
// Concrete types implementing Base. struct Foo(u32); impl Base for Foo {} struct Bar(f64); impl Base for Bar {}
fn main() {
// Create a trait object.
let mut base: Box
// Try sequential downcasts.
if let Some(foo) = base.downcast_ref::<Foo>() {
assert_eq!(foo.0, 42);
} else if let Some(bar) = base.downcast_ref::<Bar>() {
assert_eq!(bar.0, 42.0);
}
assert!(base.is::<Foo>());
} ```
```rust
extern crate downcastrs; use downcastrs::Downcast;
// To create a trait with downcasting methods, extend Downcast
and run
// impldowncast!() on the trait.
trait Base
// Concrete types implementing Base.
struct Foo(u32);
impl Base
fn main() {
// Create a trait object.
let mut base: Box
// Try sequential downcasts.
if let Some(foo) = base.downcast_ref::<Foo>() {
assert_eq!(foo.0, 42);
} else if let Some(bar) = base.downcast_ref::<Bar>() {
assert_eq!(bar.0, 42.0);
}
assert!(base.is::<Bar>());
} ```
Copyright 2015, Ashish Myles. This software is dual-licensed under the MIT and Apache 2.0 licenses.