summaryrefslogblamecommitdiff
path: root/rust-book/functional/src/main.rs
blob: 7749e58c1b788e289bcb633e7113b4cd29d0e320 (plain) (tree)



























































































































































































                                                                         
//use std::thread;
//use std::time::Duration;
//
//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
//            },
//        }
//    }
//}
//
//fn main() {
//    let simulated_user_specified_value = 26;
//    let simulated_random_number = 3;
//
//    generate_workout(
//        simulated_user_specified_value,
//        simulated_random_number
//    );
//}
//
//fn generate_workout(intensity: u32, random_number: u32) {
//    let mut expensive_result = Cacher::new(|num| {
//        println!("calculating slowly...");
//        thread::sleep(Duration::from_secs(2));
//        num
//    });
//
//    if intensity < 25 {
//        println!(
//            "Today, do {} pushups!",
//            expensive_result.value(intensity)
//        );
//        println!(
//            "Next, do {} situps!",
//            expensive_result.value(intensity)
//        );
//    }
//    else {
//        if random_number == 3 {
//            println!("Take a break today! Remember to stay hydrated!");
//        }
//        else {
//            println!(
//                "Today, run for {} minutes!",
//                expensive_result.value(intensity)
//            );
//        }
//    }
//}
//




fn main() {
    let v1 = vec![1, 2, 3];
    let v1_iter = v1.iter();

    for val in v1_iter {
        dbg!(val);
    }
}

#[test]
fn iterator_demonstration() {
    let v1 = vec![1, 2, 3];
    let mut v1_iter = v1.iter();

    assert_eq!(v1_iter.next(), Some(&1));
    assert_eq!(v1_iter.next(), Some(&2));
    assert_eq!(v1_iter.next(), Some(&3));
    assert_eq!(v1_iter.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);
}

#[test]
fn iterator_map() {
    let v1: Vec<i32> = vec![1, 2, 3];
    let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
    assert_eq!(v2, vec![2, 3, 4]);
}



#[derive(PartialEq, Debug)]
struct Shoe {
    size: i32,
    style: String,
}

fn shoes_in_my_size(shoes: Vec<Shoe>, shoe_size: i32) -> Vec<Shoe> {
    shoes.into_iter()
        .filter(|s| s.size == shoe_size)
        .collect()
}

#[test]
fn filters_by_size() {
    let shoes = vec![
        Shoe { size: 10, style: String::from("sneaker") },
        Shoe { size: 10, style: String::from("boot") },
        Shoe { size: 13, style: String::from("sandal") },
    ];

    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!(18, sum);
}