#![no_std]
#![feature(unboxed_closures)]
#![feature(tuple_trait)]
#![feature(const_trait_impl)]
#![feature(fn_traits)]
#![cfg_attr(feature = "async", feature(async_fn_traits))]
#![cfg_attr(feature = "async", doc = r##"
```rust
#![feature(fn_traits)]
#![feature(async_fn_traits)]
use fn_zip::*;
use core::ops::AsyncFn;
async fn a(x: f32) -> f64
{
(x as f64).sqrt()
}
async fn b(x: u8) -> u8
{
x + 1
}
let ab = a.fn_zip(b);
let (x_a, x_b) = (4.0, 23);
# tokio_test::block_on(async {
// I don't know of any prettier way to call an async function...
let (y_a, y_b) = ab.async_call((x_a, x_b)).await;
assert_eq!(y_a, a(x_a).await);
assert_eq!(y_b, b(x_b).await);
# })
```"##)]
moddef::moddef!(
flat(pub) mod {
zip,
zipped_fn,
join for cfg(feature = "async")
}
);
#[cfg(test)]
mod tests
{
use super::*;
#[test]
fn it_works()
{
fn a(x: f32) -> f64
{
(x as f64).sqrt()
}
fn b(x: u8) -> u8
{
x + 1
}
let mut ab = a.fn_zip(b);
let (x_a, x_b) = (4.0, 23);
let (y_a, y_b) = ab(x_a, x_b);
assert_eq!(y_a, a(x_a));
assert_eq!(y_b, b(x_b));
let ab = &mut ab;
let (y_a, y_b) = ab(x_a, x_b);
assert_eq!(y_a, a(x_a));
assert_eq!(y_b, b(x_b));
let ab = &*ab;
let (y_a, y_b) = ab(x_a, x_b);
assert_eq!(y_a, a(x_a));
assert_eq!(y_b, b(x_b));
}
#[cfg(feature = "async")]
#[test]
fn test_async()
{
use core::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
async fn a(x: f32) -> f64
{
(x as f64).sqrt()
}
async fn b(x: u8) -> u8
{
x + 1
}
let mut ab = a.fn_zip(b);
let (x_a, x_b) = (4.0, 23);
tokio_test::block_on(async {
let (y_a, y_b) = ab.async_call((x_a, x_b)).await;
assert_eq!(y_a, a(x_a).await);
assert_eq!(y_b, b(x_b).await);
let (y_a, y_b) = ab.async_call_mut((x_a, x_b)).await;
assert_eq!(y_a, a(x_a).await);
assert_eq!(y_b, b(x_b).await);
let (y_a, y_b) = ab.async_call_once((x_a, x_b)).await;
assert_eq!(y_a, a(x_a).await);
assert_eq!(y_b, b(x_b).await);
});
}
#[test]
fn test_const()
{
fn a(x: f32) -> f64
{
(x as f64).sqrt()
}
fn b(x: u8) -> u8
{
x + 1
}
const A: fn(f32) -> f64 = a;
const B: fn(u8) -> u8 = b;
const AB: ZippedFn<(f32,), (u8,), fn(f32) -> f64, fn(u8) -> u8> = A.fn_zip_once(B);
let (x_a, x_b) = (4.0, 23);
let (y_a, y_b) = AB(x_a, x_b);
assert_eq!(y_a, a(x_a));
assert_eq!(y_b, b(x_b));
}
}