1 extern crate downcast;
2 
3 use downcast::{downcast, Any};
4 use std::fmt::Debug;
5 
6 /* Trait */
7 
8 trait Animal<X: Debug>: Any {
what_am_i(&self)9     fn what_am_i(&self);
get_item(&self) -> Option<&X>10     fn get_item(&self) -> Option<&X>;
11 }
12 
13 downcast!(<X> dyn Animal<X> where X: Debug);
14 
15 /* Impl */
16 
17 struct Bird<X>{ item: Option<X> }
18 
19 impl<X: Debug + 'static> Animal<X> for Bird<X> {
what_am_i(&self)20     fn what_am_i(&self){
21         println!("Im a bird!")
22     }
get_item(&self) -> Option<&X>23     fn get_item(&self) -> Option<&X> {
24         match self.item {
25             Some(ref item) => println!("I'm holding a {:?}! Look, see!", item),
26             None => println!("I'm holding nothing!")
27         }
28         self.item.as_ref()
29     }
30 }
31 
32 impl<X: Debug + 'static> Bird<X> {
eat_item(&mut self)33     fn eat_item(&mut self) {
34         if self.item.is_some() {
35             let item = self.item.take().unwrap();
36             println!("I ate the {:?}! I hope it was edible!", item)
37         } else {
38             println!("I don't have anything to eat!")
39         }
40     }
41 }
42 
43 /* Main */
44 
main()45 fn main() {
46     let mut animal: Box<dyn Animal<String>> = Box::new(Bird{ item: Some("haselnut".to_owned()) });
47     animal.what_am_i();
48     {
49         let bird = animal.downcast_mut::<Bird<String>>().unwrap();
50         bird.get_item();
51         bird.eat_item();
52     }
53     let mut bird = animal.downcast::<Bird<String>>().ok().unwrap();
54     bird.get_item();
55     bird.eat_item();
56 }
57