fn_compose/
lib.rs

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}