mcurry 0.1.1

Macros for creating curried functions.
Documentation
/// Creates a curried function.
///
/// The given function definition should be specified in the form
///
/// ```text
/// (arg ->)+ (*|@return_type) {
///     function_body
/// }
/// ```
///
/// No types are specified on the function parameters. An explicit return type can be specified
/// with a type preceded by an `@`; specifying `*` will deduce the return type. The macro will not
/// perform any type conversions.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate mcurry;
/// # fn main() {
/// let add_3 = curry!(a -> b -> c -> * {
///   a + b + c
/// });
///
/// assert_eq!(add_3(13)(71)(26), 110);
/// # }
/// ```
///
/// ```
/// # #[macro_use] extern crate mcurry;
/// # fn main() {
/// let haiku = curry!(a -> b -> c -> @String {
///   let lines = vec![a, b, c];
///   lines.join("\n")
/// });
///
/// assert_eq!(haiku("The first cold shower")
///                 ("Even the monkey seems to want")
///                 ("A little coat of straw"),
///
///                 "The first cold shower\n\
///                  Even the monkey seems to want\n\
///                  A little coat of straw");
/// # }
/// ```
///
/// ```compile_fail
/// # #[macro_use] extern crate mcurry;
/// # fn main() {
/// let add_3 = curry!(a -> b -> c -> @usize {
///   a + b + c // error; evaluates to i32
/// });
///
/// assert_eq!(add_3(13)(71)(26), 110);
/// # }
/// ```
#[macro_export]
macro_rules! curry(
    ($($arg:ident ->)+ * $body:block) => {
        $(move |$arg|)* $body
    };

    ($($arg:ident ->)+ @$ret:ty $body:block) => {
        $(move |$arg|)* -> $ret { $body }
    };
);

#[cfg(test)]
mod test {
    #[test]
    fn test_return_elided() {
        let div_minus = curry!(n -> m -> o -> * {
            let div = n / m;
            div - o
        });
        assert_eq!(div_minus(100)(4)(5), 20);
    }

    #[test]
    fn test_return_specified() {
        let div_minus = curry!(n -> m -> o -> @i32 {
            let div = n / m;
            div - o
        });
        assert_eq!(div_minus(100)(4)(5), 20);
    }
}