currying 0.4.1

A crate for currying anything implementing `FnOnce`. Arguments can be passed one at a time, yielding a new something implementing `FnOnce` (and possibly `FnMut` and `Fn`) which can be called with one less argument.
Documentation
#![no_std]
#![forbid(unsafe_code)]
#![feature(tuple_trait)]
#![feature(unboxed_closures)]
#![feature(fn_traits)]
#![feature(trait_alias)]
#![feature(const_trait_impl)]
#![feature(const_precise_live_drops)]
#![feature(async_fn_traits)]
#![feature(specialization)]

#![cfg_attr(all(feature = "rcurry", feature = "8"), doc = r#"A crate for currying functions in rust

Arguments can be passed one at a time, yielding a new something implementing [FnOnce](core::ops::FnOnce)
(and possibly [FnMut](core::ops::FnMut) and [Fn](core::ops::Fn)) which can be called with one less argument.

It also implements [AsyncFnOnce](core::ops::AsyncFnOnce), [AsyncFnMut](core::ops::AsyncFnMut) and [AsyncFn](core::ops::AsyncFn) if the feature `async` is enabled,
since this is an experimental feature.

Curried arguments are then omitted when calling the curried function, as they have already been passed.

# Examples

```rust
use currying::*;

let f = |x, y, z| x + y + z;
let (x, y, z) = (1, 2, 3);

let fx = f.curry(x);

assert_eq!(fx(y, z), f(x, y, z));

let fxz = fx.rcurry(z);

assert_eq!(fxz(y), f(x, y, z));

let fxyz = fxz.curry(y);

assert_eq!(fxyz(), f(x, y, z));
```

Currying also works at compile-time.

```rust
# #![feature(const_trait_impl)]
use currying::*;

const fn f(x: u8, y: u8, z: u8) -> u8 {
    x + y + z
}

const X: u8 = 1;
const Y: u8 = 2;
const Z: u8 = 3;

const {
    let fx = f.curry(X);

    assert!(fx(Y, Z) == f(X, Y, Z));

    let fxz = fx.rcurry(Z);

    assert!(fxz(Y) == f(X, Y, Z));

    let fxyz = fxz.curry(Y);

    assert!(fxyz() == f(X, Y, Z));
}
```"#)]
#![cfg_attr(all(feature = "rcurry", not(feature = "8")), doc = r#"A crate for currying functions in rust

Arguments can be passed one at a time, yielding a new something implementing [FnOnce](core::ops::FnOnce)
(and possibly [FnMut](core::ops::FnMut) and [Fn](core::ops::Fn)) which can be called with one less argument.

It also implements [AsyncFnOnce](core::ops::AsyncFnOnce), [AsyncFnMut](core::ops::AsyncFnMut) and [AsyncFn](core::ops::AsyncFn) if the feature `async` is enabled,
since this is an experimental feature.

Curried arguments are then omitted when calling the curried function, as they have already been passed.

# Examples

```rust
use currying::*;

let f = |x, y, z| x + y + z;
let (x, y, z) = (1, 2, 3);

let fx = f.curry(x);

assert_eq!(fx(y, z), f(x, y, z));

let fxz = fx.rcurry(z);

assert_eq!(fxz(y), f(x, y, z));

let fxyz = fxz.curry(y);

assert_eq!(fxyz(), f(x, y, z));
```"#)]
#![cfg_attr(all(not(feature = "rcurry"), feature = "8"), doc = r#"A crate for currying functions in rust

Arguments can be passed one at a time, yielding a new something implementing [FnOnce](core::ops::FnOnce)
(and possibly [FnMut](core::ops::FnMut) and [Fn](core::ops::Fn)) which can be called with one less argument.

It also implements [AsyncFnOnce](core::ops::AsyncFnOnce), [AsyncFnMut](core::ops::AsyncFnMut) and [AsyncFn](core::ops::AsyncFn) if the feature `async` is enabled,
since this is an experimental feature.

Curried arguments are then omitted when calling the curried function, as they have already been passed.

# Examples

```rust
use currying::*;

let f = |x, y, z| x + y + z;
let (x, y, z) = (1, 2, 3);

let fx = f.curry(x);

assert_eq!(fx(y, z), f(x, y, z));

let fxy = fx.curry(y);

assert_eq!(fxy(z), f(x, y, z));

let fxyz = fxy.curry(z);

assert_eq!(fxyz(), f(x, y, z));
```

Currying also works at compile-time.

```rust
# #![feature(const_trait_impl)]
use currying::*;

const fn f(x: u8, y: u8, z: u8) -> u8 {
    x + y + z
}

const X: u8 = 1;
const Y: u8 = 2;
const Z: u8 = 3;

const {
    let fx = f.curry(X);

    assert!(fx(Y, Z) == f(X, Y, Z));

    let fxy = fx.curry(Y);

    assert!(fxy(Z) == f(X, Y, Z));

    let fxyz = fxy.curry(Z);

    assert!(fxyz() == f(X, Y, Z));
}
```"#)]
#![cfg_attr(all(not(feature = "rcurry"), not(feature = "8")), doc = r#"A crate for currying functions in rust

Arguments can be passed one at a time, yielding a new something implementing [FnOnce](core::ops::FnOnce)
(and possibly [FnMut](core::ops::FnMut) and [Fn](core::ops::Fn)) which can be called with one less argument.

It also implements [AsyncFnOnce](core::ops::AsyncFnOnce), [AsyncFnMut](core::ops::AsyncFnMut) and [AsyncFn](core::ops::AsyncFn) if the feature `async` is enabled,
since this is an experimental feature.

Curried arguments are then omitted when calling the curried function, as they have already been passed.

# Examples

```rust
use currying::*;

let f = |x, y, z| x + y + z;
let (x, y, z) = (1, 2, 3);

let fx = f.curry(x);

assert_eq!(fx(y, z), f(x, y, z));

let fxy = fx.curry(y);

assert_eq!(fxy(z), f(x, y, z));

let fxyz = fxy.curry(z);

assert_eq!(fxyz(), f(x, y, z));
```"#)]

moddef::moddef!(
    flat(pub) mod {
        curried,
        curry,
        rcurry for cfg(feature = "rcurry"),
        concat_args
    }
);

#[cfg(test)]
mod test
{
    #[cfg(feature = "rcurry")]
    #[test]
    fn test()
    {
        use crate::*;

        let f = |x, y, z| x + y + z;
        let (x, y, z) = (1, 2, 3);

        let fx = f.curry(x);

        assert_eq!(fx(y, z), f(x, y, z));

        let fxz = fx.rcurry(z);

        assert_eq!(fxz(y), f(x, y, z));

        let fxyz = fxz.curry(y);

        assert_eq!(fxyz(), f(x, y, z));
    }

    #[test]
    fn test_mut()
    {
        use crate::Curry;

        let i0 = 0;
        let mut i = i0;
        let n = 1;

        let mut f = |j| {
            i += j;
            i
        };

        let mut fj = f.curry_mut(n);

        for k in 1..10
        {
            assert_eq!(fj(), i0 + k * n)
        }
    }

    #[test]
    fn test_once()
    {
        use crate::Curry;

        let i0 = 0;
        let i = i0;
        let n = 1;

        let f = |j| i + j;

        let i = f.curry_once(n)();

        assert_eq!(i, i0 + n)
    }

    #[cfg(all(feature = "rcurry", feature = "8"))]
    #[test]
    fn test_const()
    {
        use crate::*;

        const fn f(x: u8, y: u8, z: u8) -> u8
        {
            x + y + z
        }

        const X: u8 = 1;
        const Y: u8 = 2;
        const Z: u8 = 3;

        const {
            let fx = f.curry(X);

            assert!(fx(Y, Z) == f(X, Y, Z));

            let fxz = fx.rcurry(Z);

            assert!(fxz(Y) == f(X, Y, Z));

            let fxyz = fxz.curry(Y);

            assert!(fxyz() == f(X, Y, Z));
        }
    }
}