rust_overture/
pipe.rs

1// pipe.rs
2
3/// Pipe two functions (non-fallible)
4pub fn pipe<A, B, C>(
5    f: impl Fn(A) -> B + 'static,
6    g: impl Fn(B) -> C + 'static,
7) -> impl Fn(A) -> C {
8    move |a| g(f(a))
9}
10
11pub fn pipe3<A, B, C, D>(
12    f: impl Fn(A) -> B + 'static,
13    g: impl Fn(B) -> C + 'static,
14    h: impl Fn(C) -> D + 'static,
15) -> impl Fn(A) -> D {
16    move |a| h(g(f(a)))
17}
18
19pub fn pipe4<A, B, C, D, E>(
20    f: impl Fn(A) -> B + 'static,
21    g: impl Fn(B) -> C + 'static,
22    h: impl Fn(C) -> D + 'static,
23    i: impl Fn(D) -> E + 'static,
24) -> impl Fn(A) -> E {
25    move |a| i(h(g(f(a))))
26}
27
28pub fn pipe5<A, B, C, D, E, F>(
29    f: impl Fn(A) -> B + 'static,
30    g: impl Fn(B) -> C + 'static,
31    h: impl Fn(C) -> D + 'static,
32    i: impl Fn(D) -> E + 'static,
33    j: impl Fn(E) -> F + 'static,
34) -> impl Fn(A) -> F {
35    move |a| j(i(h(g(f(a)))))
36}
37
38pub fn pipe6<A, B, C, D, E, F, G>(
39    f: impl Fn(A) -> B + 'static,
40    g: impl Fn(B) -> C + 'static,
41    h: impl Fn(C) -> D + 'static,
42    i: impl Fn(D) -> E + 'static,
43    j: impl Fn(E) -> F + 'static,
44    k: impl Fn(F) -> G + 'static,
45) -> impl Fn(A) -> G {
46    move |a| k(j(i(h(g(f(a))))))
47}
48
49/// Pipe two functions that return Result
50pub fn pipe_result<A, B, C, E>(
51    f: impl Fn(A) -> Result<B, E> + 'static,
52    g: impl Fn(B) -> Result<C, E> + 'static,
53) -> impl Fn(A) -> Result<C, E> {
54    move |a| f(a).and_then(|b| g(b))
55}
56
57pub fn pipe_result3<A, B, C, D, E>(
58    f: impl Fn(A) -> Result<B, E> + 'static,
59    g: impl Fn(B) -> Result<C, E> + 'static,
60    h: impl Fn(C) -> Result<D, E> + 'static,
61) -> impl Fn(A) -> Result<D, E> {
62    move |a| f(a).and_then(|b| g(b)).and_then(|c| h(c))
63}
64
65// Similarly define pipe_result4, pipe_result5, pipe_result6 if needed
66
67#[macro_export]
68macro_rules! pipe_macro {
69    ($f:expr, $g:expr) => {
70        crate::pipe::pipe($f, $g)
71    };
72    ($f:expr, $g:expr, $h:expr) => {
73        crate::pipe::pipe3($f, $g, $h)
74    };
75    ($f:expr, $g:expr, $h:expr, $i:expr) => {
76        crate::pipe::pipe4($f, $g, $h, $i)
77    };
78    ($f:expr, $g:expr, $h:expr, $i:expr, $j:expr) => {
79        crate::pipe::pipe5($f, $g, $h, $i, $j)
80    };
81    ($f:expr, $g:expr, $h:expr, $i:expr, $j:expr, $k:expr) => {
82        crate::pipe::pipe6($f, $g, $h, $i, $j, $k)
83    };
84}
85
86#[macro_export]
87macro_rules! pipe_result {
88    ($f:expr, $g:expr) => {
89        crate::pipe::pipe_result($f, $g)
90    };
91    ($f:expr, $g:expr, $h:expr) => {
92        crate::pipe::pipe_result3($f, $g, $h)
93    };
94}