part11: first version
[rust-101.git] / workspace / src / part11.rs
1 // Rust-101, Part 11: Trait Objects, Box (WIP)
2 // ===========================================
3
4
5 mod callbacks {
6     // For now, we just decide that the callbakcs have an argument of type `i32`.
7     struct CallbacksV1<F: FnMut(i32)> {
8         callbacks: Vec<F>,
9     }
10
11     /* struct CallbacksV2 {
12         callbacks: Vec<FnMut(i32)>,
13     } */
14
15     struct Callbacks {
16         callbacks: Vec<Box<FnMut(i32)>>,
17     }
18
19     impl Callbacks {
20         // Now we can provide some functions. The constructor should be straight-forward.
21         fn new() -> Self {
22             unimplemented!()
23         }
24
25         // Registration simply stores the callback.
26         fn register(&mut self, callback: Box<FnMut(i32)>) {
27             unimplemented!()
28         }
29
30         // And here we call all the stored callbacks.
31         fn call(&mut self, val: i32) {
32             // Since they are of type `FnMut`, we need to mutably iterate. Notice that boxes dereference implicitly.
33             for callback in self.callbacks.iter_mut() {
34                 unimplemented!()
35             }
36         }
37     }
38
39     // Now we are read for the demo.
40     pub fn demo() {
41         let mut c = Callbacks::new();
42         c.register(Box::new(|val| println!("Callback 1: {}", val)));
43
44         c.call(0);
45
46         let mut count: usize = 0;
47         c.register(Box::new(move |val| { count = count+1; println!("Callback 2, {}. time: {}", count, val); } ));
48         c.call(1);
49         c.call(2);
50     }
51
52 }
53
54 // Remember to edit `main.rs` to run the demo.
55 pub fn main() {
56     callbacks::demo();
57 }
58
59 mod callbacks_clone {
60
61     use std::rc;
62
63     #[derive(Clone)]
64     struct Callbacks {
65         callbacks: Vec<rc::Rc<Fn(i32)>>,
66     }
67
68     // The methods on these clonable callbacks are just like the ones above.
69     impl Callbacks {
70         fn new() -> Self {
71             unimplemented!()
72         }
73
74         fn register(&mut self, callback: rc::Rc<Fn(i32)>) {
75             unimplemented!()
76         }
77
78         fn call(&mut self, val: i32) {
79             // We only need a shared iterator here. `Rc` also implicitly dereferences, so we can just call the callback.
80             for callback in self.callbacks.iter() {
81                 unimplemented!()
82             }
83         }
84     }
85
86     // The demo works just as above. Our counting callback doesn't work anymore though, because we are using `Fn` now.
87     fn demo() {
88         let mut c = Callbacks::new();
89         c.register(rc::Rc::new(|val| println!("Callback 1: {}", val)));
90
91         c.call(0);
92         c.call(1);
93     }
94 }
95
96 // **Exercise 11.1**: We made the arbitrary choice of using `i32` for the arguments. Generalize the data-structures above
97 // to work with an arbitrary type `T` that's passed to the callbacks. Since you need to call multiple callbacks with the
98 // same `t: T`, you will either have to restrict `T` to `Copy` types, or pass a borrow.
99