Skip to content

Commit cc092a6

Browse files
committed
1 parent 5302d2c commit cc092a6

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ mod from_fn;
9191
mod iter;
9292
mod sizes;
9393
mod traits;
94+
mod zip;
9495

9596
pub use crate::{iter::TryFromIteratorError, traits::*};
9697
pub use typenum;

src/zip.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//! Functional programming with [`Array`]s.
2+
// This is modeled after `generic-array::functional`
3+
// see: <https://docs.rs/generic-array/1.0.0/generic_array/functional/index.html>
4+
5+
use crate::{Array, ArraySize};
6+
7+
impl<T, U> Array<T, U>
8+
where
9+
U: ArraySize,
10+
{
11+
/// Combines two `Array` instances and iterates through both of them, initialization a new
12+
/// `Array` with the result of the zipped mapping function.
13+
///
14+
/// If the mapping function panics, any already initialized elements in the new array will
15+
/// be dropped, AND any unused elements in the source arrays will also be dropped.
16+
#[inline(always)]
17+
pub fn zip<Rhs, F, O>(self, rhs: Array<Rhs, U>, f: F) -> Array<O, U>
18+
where
19+
U: ArraySize,
20+
F: FnMut(T, Rhs) -> O,
21+
{
22+
Zipper {
23+
inner: self.into_iter(),
24+
rhs: rhs.into_iter(),
25+
f,
26+
}
27+
.collect()
28+
}
29+
}
30+
31+
struct Zipper<I, R, F> {
32+
inner: I,
33+
rhs: R,
34+
f: F,
35+
}
36+
37+
impl<I, T, R, RT, O, F> Iterator for Zipper<I, R, F>
38+
where
39+
I: Iterator<Item = T>,
40+
R: Iterator<Item = RT>,
41+
F: FnMut(T, RT) -> O,
42+
{
43+
type Item = O;
44+
45+
#[inline(always)]
46+
fn next(&mut self) -> Option<Self::Item> {
47+
Some((self.f)(self.inner.next()?, self.rhs.next()?))
48+
}
49+
}

tests/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,18 @@ fn maybe_uninit() {
139139
let array = unsafe { uninit_array.assume_init() };
140140
assert_eq!(array.as_slice(), EXAMPLE_SLICE);
141141
}
142+
143+
#[test]
144+
fn test_functional_map() {
145+
let base = Array::<u8, U4>::from([1, 2, 3, 4]);
146+
let expected = Array::<u8, U4>::from([2, 3, 4, 5]);
147+
assert_eq!(base.map(|item| item + 1), expected);
148+
}
149+
150+
#[test]
151+
fn test_functional_zip() {
152+
let base = Array::<u8, U4>::from([1, 2, 3, 4]);
153+
let with = Array::<u8, U4>::from([2, 3, 4, 5]);
154+
let expected = Array::<u8, U4>::from([2, 6, 12, 20]);
155+
assert_eq!(base.zip(with, |item, rhs| item * rhs), expected);
156+
}

0 commit comments

Comments
 (0)