d4805e7dbfef6dfdf15444b4e70148cc58478ed6
[rust-101.git] / src / part03.rs
1 // Rust-101, Part 03: Input, Formatting
2 // ====================================
3
4 use std::io::prelude::*;
5 use std::io;
6
7 fn read_vec() -> Vec<i32> {
8     let mut vec = Vec::new();
9
10     let stdin = io::stdin();
11     println!("Enter a list of numbers, one per line. End with Ctrl-D.");
12     for line in stdin.lock().lines() {
13         let line = line.unwrap();
14         match line.parse::<i32>() {
15             Ok(num) => vec.push(num),
16             Err(_) => println!("What did I say about numbers?"),
17         }
18     }
19
20     vec
21 }
22
23 enum SomethingOrNothing<T>  {
24     Something(T),
25     Nothing,
26 }
27 use self::SomethingOrNothing::{Something,Nothing};
28
29 trait Minimum : Copy {
30     fn min(a: Self, b: Self) -> Self;
31 }
32
33 fn vec_min<T: Minimum>(v: Vec<T>) -> SomethingOrNothing<T> {
34     let mut min = Nothing;
35     for e in v {
36         min = Something(match min {
37             Nothing => e,
38             Something(n) => T::min(n, e)
39         });
40     }
41     min
42 }
43
44 impl Minimum for i32 {
45     fn min(a: Self, b: Self) -> Self {
46         ::std::cmp::min(a, b)
47     }
48 }
49
50 impl SomethingOrNothing<i32> {
51     fn print(self) {
52         match self {
53             Nothing => println!("The number is: <nothing>"),
54             Something(n) => println!("The number is: {}", n),
55         };
56     }
57 }
58 pub fn part_main() {
59     let vec = read_vec();
60     let min = vec_min(vec);
61     min.print();
62 }
63
64 impl SomethingOrNothing<i32> {
65     fn equals(self, other: Self) -> bool {
66         match (self, other) {
67             (Nothing     , Nothing      ) => true,
68             (Something(n), Something (m)) => n == m,
69             _ => false,
70         }
71     }
72 }
73
74 #[test]
75 fn tes_vec_min() {
76     assert!(vec_min(vec![6,325,33,532,5,7]).equals(Something(5)));
77     assert!(vec_min(vec![]).equals(Nothing));
78 }
79
80 // [index](main.html) | [previous](part02.html) | next