pub mod vector {
pub fn init<T>(capacity: usize, f: fn(usize) -> T) -> Vec<T> {
let mut v = Vec::with_capacity(capacity);
for i in 0..capacity {
v.push(f(i));
}
v
}
pub fn zip_with<T, U, V>(mut first: Vec<T>, mut second: Vec<U>, with: fn(T, U) -> V) -> Vec<V> {
if first.len() != second.len() {
panic!("You need to have equal lists");
}
let length = first.len();
let mut v = Vec::with_capacity(length);
for _ in 0..length {
let x = first.drain(0..1).next().unwrap();
let y = second.drain(0..1).next().unwrap();
v.push(with(x, y));
}
v
}
pub fn zip<T, U>(first: Vec<T>, second: Vec<U>) -> Vec<(T, U)> {
zip_with(first, second, |x, y| (x, y))
}
}
pub mod truth {
pub fn all<'a, T>(elems: &'a Vec<T>, f: fn(&'a T) -> bool) -> bool {
elems.iter().fold(true, |acc, x| acc && f(x))
}
pub fn any<'a, T>(elems: &'a Vec<T>, f: fn(&'a T) -> bool) -> bool {
elems.iter().fold(false, |acc, x| acc || f(x))
}
}
pub mod futures {
#[macro_export]
macro_rules! pipe {
($init:tt $(=>$fn:ident)+) => {{
let mut r = $init;
$( r = $fn(r).await; )*
r
}}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vec_init() {
let v = vector::init(4, |x| x.pow(2));
assert_eq!(v[0], 0);
assert_eq!(v[1], 1);
assert_eq!(v[2], 4);
assert_eq!(v[3], 9);
println!("{:?}", v);
}
#[test]
fn test_zip_with() {
let xs = vec![1, 2, 3];
let ys = vec![4, 5, 6];
assert_eq!(vector::zip_with(xs, ys, |x, y| x + y), vec![5, 7, 9]);
}
#[test]
fn test_zip() {
let xs = vec![1, 2, 3];
let ys = vec![4, 5, 6];
let zs = vector::zip(xs, ys);
println!("{:?}", zs);
assert_eq!(zs[0], (1, 4));
assert_eq!(zs[1], (2, 5));
assert_eq!(zs[2], (3, 6));
}
#[test]
fn test_all() {
let xs = vec![1, 3, 5, 7, 9];
let is_odd = |x| x % 2 != 0;
assert_eq!(truth::all(&xs, is_odd), true)
}
#[test]
fn test_any() {
let xs = vec![1, 4, 5, 7, 9];
let is_even = |x| x % 2 == 0;
assert_eq!(truth::any(&xs, is_even), true)
}
async fn double(x: i32) -> i32 {
x + x
}
async fn square(x: i32) -> i32 {
x * x
}
#[tokio::test]
async fn test_piping() {
let x = pipe!(2
=> double
=> square
=> double
=> square);
assert_eq!(x, 1024);
}
}