diff --git a/Cargo.toml b/Cargo.toml index 9e8567d..490c7db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ license = "MIT/Apache-2.0" keywords = ["FEC", "ErrorCorrection", "FountainCode"] [dependencies] +num-traits = "0.2" rand = "0.7.3" [dev-dependencies] diff --git a/src/iterext.rs b/src/iterext.rs new file mode 100644 index 0000000..1a801b3 --- /dev/null +++ b/src/iterext.rs @@ -0,0 +1,59 @@ +use num_traits::Zero; +use std::ops; + +/// Crate-local iterator extensions. +pub(crate) trait IterExt: Iterator { + fn cumsum(self) -> CumSum + where + S: Zero, + Self: Sized, + { + CumSum { + iter: self, + sum: S::zero(), + } + } +} + +impl IterExt for I where I: Iterator {} + +pub(crate) struct CumSum { + iter: I, + sum: S, +} + +impl Iterator for CumSum +where + I: Iterator, + S: ops::AddAssign + Copy, +{ + type Item = S; + fn next(&mut self) -> Option { + self.iter.next().map(|elem| { + self.sum += elem; + self.sum + }) + } +} + +#[cfg(test)] +mod tests { + use super::IterExt; + + #[test] + fn cumsum_test_i32() { + let input = [1_i32, 1, 1, 1, 1, 1]; + let csum: Vec = input.iter().cumsum().collect(); + let expected = [1_i32, 2, 3, 4, 5, 6]; + assert_eq!(&csum, &expected); + } + + #[test] + #[allow(clippy::float_cmp)] + fn cumsum_test_f32() { + let input = [1.0_f32, 1.0, 1.0, 1.0, 1.0, 1.0]; + let csum: Vec = input.iter().cumsum().collect(); + let expected = [1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0]; + assert_eq!(&csum, &expected); + } +} diff --git a/src/lib.rs b/src/lib.rs index 07eb5e5..4a1e781 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,4 +2,5 @@ pub mod block; pub mod decoder; pub mod droplet; pub mod encoder; +mod iterext; pub mod soliton;