Skip to main content

restaurant/
cacher.rs

1use std::thread;
2use std::time::Duration;
3
4struct Cacher<T>
5    where T: Fn(u32) -> u32
6{
7    calculation: T,
8    value: Option<u32>,
9}
10
11impl<T> Cacher<T>
12    where T: Fn(u32) -> u32
13{
14    fn new(calculation: T) -> Cacher<T> {
15        Cacher {
16            calculation,
17            value: None,
18        }
19    }
20
21    fn value(&mut self, arg: u32) -> u32 {
22        match self.value {
23            Some(v) => v,
24            None => {
25                let v = (self.calculation)(arg);
26                self.value = Some(v);
27                v
28            },
29        }
30    }
31}
32
33fn generate_workout(intensity: u32, random_number: u32) {
34    let mut expensive_result = Cacher::new(|num| {
35        println!("calculating slowly...");
36        thread::sleep(Duration::from_secs(2));
37        num
38    });
39
40    if intensity < 25 {
41        println!(
42            "Today, do {} pushups!",
43            expensive_result.value(intensity)
44        );
45        println!(
46            "Next, do {} situps!",
47            expensive_result.value(intensity)
48        );
49    } else {
50        if random_number == 3 {
51            println!("Take a break today! Remember to stay hydrated!");
52        } else {
53            println!(
54                "Today, run for {} minutes!",
55                expensive_result.value(intensity)
56            );
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    // $ cargo test -- --ignored
66    // $ cargo test slow -- --ignored
67    # [test]
68    # [ignore]
69    fn slow_cache() {
70        let simulated_user_specified_value = 10;
71        let simulated_random_number = 7;
72
73        generate_workout(
74            simulated_user_specified_value,
75            simulated_random_number
76        );
77    }
78
79    #[test]
80    fn call_with_different_values() {
81        let mut c = Cacher::new(|a| a);
82
83        let v1 = c.value(1);
84        let v2 = c.value(2);
85
86        assert_eq!(v2, 2);
87    }
88}
89