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 { |
9 | fn what_am_i(&self); |
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> { |
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 | |
32 | impl<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 | |
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 | |