1extern crate downcast;
2
3use downcast::{downcast, Any};
4use std::fmt::Debug;
5
6/* Trait */
7
8trait Animal<X: Debug>: Any {
9 fn what_am_i(&self);
10 fn get_item(&self) -> Option<&X>;
11}
12
13downcast!(<X> dyn Animal<X> where X: Debug);
14
15/* Impl */
16
17struct Bird<X>{ item: Option<X> }
18
19impl<X: Debug + 'static> Animal<X> for Bird<X> {
20 fn what_am_i(&self){
21 println!("Im a bird!")
22 }
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
32impl<X: Debug + 'static> Bird<X> {
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
45fn 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