use std::thread;
use std::time::Duration;
fn simulated_expensive_calculation(num: u32) -> u32 {
println!("calculate is slowly ...");
thread::sleep(Duration::from_secs(2));
num
}
pub fn generate_workout(intensity: u32, random_number: u32) {
let mut calculation_closure = Cacher::new(|num| {
println!("calculate is slowly ...");
thread::sleep(Duration::from_secs(2));
num
});
if intensity > 25 {
println!("Today, do {} pushups!", calculation_closure.value(intensity));
println!("Next, do {} situps!", calculation_closure.value(intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!("Today, run for {} minutes!", calculation_closure.value(intensity));
}
}
}
struct Cacher<T> where T: Fn(u32) -> u32 {
calculation: T,
value: Option<u32>
}
impl<T> Cacher<T> where T: Fn(u32) -> u32 {
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: None,
}
}
fn value(&mut self, arg: u32) -> u32 {
match self.value {
Some(v) => v,
None => {
let v = (self.calculation)(arg);
self.value = Some(v);
v
},
}
}
}
#[test]
fn iterator_demonstration() {
let v1 = vec![1,2,3];
let mut v1_item = v1.iter();
assert_eq!(v1_item.next(), Some(&1));
assert_eq!(v1_item.next(), Some(&2));
assert_eq!(v1_item.next(), Some(&3));
assert_eq!(v1_item.next(), None);
}
#[test]
fn iterator_sum() {
let v1 = vec![1,2,3];
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
assert_eq!(total, 6);
}
#[derive(PartialEq, Debug)]struct Shoe {
size: u32,
style: String,
}
fn shoes_in_my_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
shoes.into_iter()
.filter(|shoe| shoe.size == shoe_size).collect()}
#[test]
fn filters_by_size() {
let shoes = vec![
Shoe {size: 10, style: String::from("sneaker")},
Shoe {size: 12, style: String::from("sandal")},
Shoe {size: 10, style: String::from("boot")},
];
let in_my_size = shoes_in_my_size(shoes, 10);
assert_eq!(
in_my_size,
vec![
Shoe {size: 10, style: String::from("sneaker")},
Shoe {size: 10, style: String::from("boot")},
],
);
}
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter {
count: 0,
}
}
}
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
self.count += 1;
if self.count < 6 {
Some(self.count)
} else {
None
}
}
}
#[test]
fn calling_next_directly() {
let mut counter = Counter::new();
assert_eq!(counter.next(), Some(1));
assert_eq!(counter.next(), Some(2));
assert_eq!(counter.next(), Some(3));
assert_eq!(counter.next(), Some(4));
assert_eq!(counter.next(), Some(5));
assert_eq!(counter.next(), None);
}
#[test]
fn using_other_iterator_trait_methods() {
let sum: u32 = Counter::new().zip(Counter::new().skip(1))
.map(|(a, b)| a * b)
.filter(|x| x % 3 == 0)
.sum();
assert_eq!(sum, 18);
}
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents.lines()
.filter(|s| s.contains(query))
.collect()
}