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