Skip to content
/ fn_zip Public

Provides a zip trait for functions, allowing two functions to be combined at compile-time before being called.

License

Notifications You must be signed in to change notification settings

sigurd4/fn_zip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status (nightly) Build Status (nightly, all features)

Build Status (stable) Build Status (stable, all features)

Test Status Lint Status

Latest Version License:MIT Documentation Coverage Status

fn_zip

Provides a zip trait for functions, allowing two functions to be combined before being called. This is equivalent to core::future::join!(), but lazy, and works for non-async functions.

The resulting function takes the arguments of both functions and return a tuple.

Example

use fn_zip::*;

fn a(x: f32) -> f64
{
    (x as f64).sqrt()
}
fn b(x: u8) -> u8
{
    x + 1
}
let ab = a.fn_zip(b); // (f32, u8) -> (f64, u8)

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));

Async

The zipped functions can also implement AsyncFnOnce, AsyncFnMut and AsyncFn if both functions qualify.

This is an experimental feature, since it just recently (as of writing) got added to the rust core library on rust-nightly, and may be subject to change at any point. Enable it with feature async or experimental.

#![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);

// 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);

Independent of this feature, it's still possible to zip two asyncronous functions normally, but their futures will not be joined.

Compile time function zipping

Functions can also be zipped during compile-time.

#![feature(const_trait_impl)]

use fn_zip::*;

fn a(x: f32) -> f64
{
    (x as f64).sqrt()
}
fn b(x: u8) -> u8
{
    x + 1
}

// Corce functions into function pointers
const A: fn(f32) -> f64 = a;
const B: fn(u8) -> u8 = b;

// Zip during compile time
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));

Tuple sizes

By default, this crate operates with function pairs of up to 16 arguments combined, and splits them up in the form of tuples. If you want to use differently sized tuples, use the features 8, 16, 32, 64, 96, 128, 160, 192, 224 or 256 to set the maximum supported tuple size.

The dont_hurt_yourself_by_using_all_features is there to prevent usage of tuples bigger than 8 if cargo is ran with the flag --all-features. Using a tuple size above 16 is highly discouraged as it will make compilation time unbearably long. Compilation time will increase exponentially. You have been warned.

About

Provides a zip trait for functions, allowing two functions to be combined at compile-time before being called.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages