From 66e7b9956833678a7911abc362031774f31ed211 Mon Sep 17 00:00:00 2001 From: Jordan Gong Date: Tue, 8 Sep 2020 20:18:34 +0800 Subject: Iterate with closures --- iterators/.gitignore | 18 ++++++++ iterators/Cargo.toml | 9 ++++ iterators/src/lib.rs | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 iterators/.gitignore create mode 100644 iterators/Cargo.toml create mode 100644 iterators/src/lib.rs diff --git a/iterators/.gitignore b/iterators/.gitignore new file mode 100644 index 0000000..e629269 --- /dev/null +++ b/iterators/.gitignore @@ -0,0 +1,18 @@ + +# Created by https://www.toptal.com/developers/gitignore/api/rust +# Edit at https://www.toptal.com/developers/gitignore?templates=rust + +### Rust ### +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# End of https://www.toptal.com/developers/gitignore/api/rust + diff --git a/iterators/Cargo.toml b/iterators/Cargo.toml new file mode 100644 index 0000000..425cbda --- /dev/null +++ b/iterators/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "iterators" +version = "0.1.0" +authors = ["Jordan Gong "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/iterators/src/lib.rs b/iterators/src/lib.rs new file mode 100644 index 0000000..01ffec3 --- /dev/null +++ b/iterators/src/lib.rs @@ -0,0 +1,125 @@ +#[derive(PartialEq, Debug)] +struct Shoe { + size: u32, + style: String, +} + +fn shoes_in_my_size(shoes: Vec, shoe_size: u32) -> Vec { + shoes.into_iter().filter(|s| s.size == shoe_size).collect() +} + +struct Counter { + count: u32, +} + +impl Counter { + fn new() -> Counter { + Counter { count: 0 } + } +} + +impl Iterator for Counter { + type Item = u32; + + fn next(&mut self) -> Option { + if self.count < 5 { + self.count += 1; + Some(self.count) + } else { + None + } + } +} + +#[cfg(test)] +mod tests { + #[test] + fn interator_demostration() { + 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_adaptor() { + let v1: Vec = vec![1, 2, 3]; + + let v2: Vec<_> = v1.iter().map(|x| x + 1).collect(); + + assert_eq!(v2, vec![2, 3, 4]); + } + + use super::*; + #[test] + fn filter_by_size() { + let shoes = vec![ + Shoe { + size: 10, + style: String::from("sneaker"), + }, + Shoe { + size: 13, + 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"), + }, + ] + ); + } + + #[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); + } +} -- cgit v1.2.3