@-ify all the things
[rust-101.git] / workspace / src / part02.rs
1 // ***Remember to enable/add this part in `main.rs`!***
2
3 // Rust-101, Part 02: Generic types, Traits
4 // ========================================
5
6
7 // ## Generic datatypes
8
9 pub enum SomethingOrNothing<T>  {
10     Something(T),
11     Nothing,
12 }
13 // Instead of writing out all the variants, we can also just import them all at once.
14 pub use self::SomethingOrNothing::*;
15 type NumberOrNothing = SomethingOrNothing<i32>;
16
17 // ## Generic `impl`, Static functions
18 // Inside an `impl`, `Self` refers to the type we are implementing things for. Here, it is
19 // an alias for `SomethingOrNothing<T>`.
20 impl<T> SomethingOrNothing<T> {
21     fn new(o: Option<T>) -> Self {
22         unimplemented!()
23     }
24
25     fn to_option(self) -> Option<T> {
26         unimplemented!()
27     }
28 }
29 // You can call static functions, and in particular constructors, as demonstrated in `call_constructor`.
30 fn call_constructor(x: i32) -> SomethingOrNothing<i32> {
31     SomethingOrNothing::new(Some(x))
32 }
33
34 // ## Traits
35
36 pub trait Minimum : Copy {
37     fn min(self, b: Self) -> Self;
38 }
39
40 pub fn vec_min<T: Minimum>(v: Vec<T>) -> SomethingOrNothing<T> {
41     let mut min = Nothing;
42     for e in v {
43         min = Something(match min {
44             Nothing => e,
45             // Here, we can now call the `min` function of the trait.
46             Something(n) => {
47                 unimplemented!()
48             }
49         });
50     }
51     min
52 }
53
54 // ## Trait implementations
55 // To make `vec_min` usable with a `Vec<i32>`, we implement the `Minimum` trait for `i32`.
56 impl Minimum for i32 {
57     fn min(self, b: Self) -> Self {
58         unimplemented!()
59     }
60 }
61
62 // We again provide a `print` function.
63 impl NumberOrNothing {
64     pub fn print(self) {
65         match self {
66             Nothing => println!("The number is: <nothing>"),
67             Something(n) => println!("The number is: {}", n),
68         };
69     }
70 }
71
72 // Now we are ready to run our new code. Remember to change `main.rs` appropriately.
73 fn read_vec() -> Vec<i32> {
74     vec![18,5,7,3,9,27]
75 }
76 pub fn main() {
77     let vec = read_vec();
78     let min = vec_min(vec);
79     min.print();
80 }
81
82
83 // **Exercise 02.1**: Change your program such that it computes the minimum of a `Vec<f32>` (where `f32` is the type
84 // of 32-bit floating-point numbers). You should not change `vec_min` in any way, obviously!
85