1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
#![no_std] #[macro_export] macro_rules! fn_compose { ( $arg: expr ) => { $arg }; ( $arg: expr => $f: ident ) => { $f($arg) }; ( $arg: expr => $f: ident $( $largs: expr, )* _ $( ,$rargs: expr )* ) => { $f($($largs,)* $arg $(,$rargs)*) }; ( $arg: expr => $f: ident => $( $tokens: tt )* ) => {{ fn_compose!($f($arg) => $($tokens)*) }}; ( $arg: expr => $f: ident $( $largs: expr, )* _ $( ,$rargs: expr )* => $( $tokens: tt )* ) => {{ fn_compose!($f($($largs,)* $arg $(,$rargs)*) => $($tokens)*) }}; } #[cfg(test)] mod tests { use super::*; #[test] fn no_fn() { assert_eq!(fn_compose!(4), 4); } #[test] fn one_simple_fn() { let add_one = |x| x + 1; assert_eq!(fn_compose!(4 => add_one), 5); } #[test] fn one_arg_fn() { let add = |x, y| x + y; assert_eq!(fn_compose!(4 => add 5, _), 9); } #[test] fn two_simple_fn() { let add_one = |x| x + 1; let double = |x| 2 * x; assert_eq!(fn_compose!(4 => double => add_one), 9); } #[test] fn two_arg_fn() { let mul = |a, b, c, d, e| a * b * c * d * e; let add = |a, b, c| a + b + c; assert_eq!(fn_compose!(4 => add 3, _, 9 => mul 1, 4, 2, _, 10), 1280); } }