Crate function_compose

Crate function_compose 

Source
Expand description

Crate function-compose provides utilities for composing functions and way to inject arguments to functions

§Composing functions

§step 1

Mark a function as composeable as below. Note that the functions must always return Result type

use function_compose::composeable;
#[composeable()]
pub fn add_10(a: i32) -> Result<i32, String> {
    Ok(a + 10)
}

#[composeable()]
pub fn add_100(a: i32) -> Result<i32, String> {
    Ok(a + 100)
}

§step 2

use compose! macro to compose the above two functions.

let result = compose!(add_10 -> add_100 -> with_args(10));
assert_eq!(220, result.unwrap());

Argument 10(from with_args(10)). is passed to add_10 function and result of add_10 is passed to add_100

§composing Async functions

It is also possible to compose sync and asycn function.

§ For async function, return type should be BoxedFuture(futures crate)
use function_compose::composeable;
use futures::{future::BoxFuture, FutureExt};
#[composeable()]
pub fn add_async(a: i32, b: i32) -> BoxFuture<'static, Result<i32, String>> {
    async move {
        let r = a + b;
        Ok(r)
    }.boxed()
}

§Composing async and sync functions usage

 use function_compose::compose;
 use fn_macros::composeable;
 use futures::{future::BoxFuture, FutureExt};
 #[composeable()]
 pub fn add_10_async(a: i32) -> BoxFuture<'static, Result<i32, String>> {
     async move {
         let r = a + 10;
         Ok(r)
     }.boxed()
 }
 #[composeable()]
 pub fn add_10(a: i32) -> Result<i32, String> {
     Ok(a + 10)
 }
 async fn test(){
    let result = compose!(add_async.add_10_async -> add_10 -> with_args(10)).await;
    assert_eq!(30, result.unwrap());
 }
 

§Injecting dependencies in multi-args function

For function with multiple arguments(say 2), One of the argument can be injected during composition itself.

§Function argument injection usage
 use function_compose::composeable;
 use futures::{future::BoxFuture, FutureExt};
 #[composeable()]
 pub fn add_3_arg_async(a: i32,b: i32, c:i32) -> BoxFuture<'static, Result<i32, String>>{
     async move{
         let  r =   a + b + c;
         Ok(r)
     }.boxed()
 }
 use crate::compose;
 let result = compose!(add_3_arg_async.provide(100).provide(200) -> add_10 -> with_args(10)).await;
 assert_eq!(320, result.unwrap());

In the above example function add_3_arg_async, out of three arguments, 2 are injected during composing the function itself (using provide(100)) . This feature could be used for injecting connection pool or a repository instance(see the example project).

§Retry in Fn Composer

Composeable macro supports retrying a function at specified interval in case of Error returned by the function. This could be useful when trying make a database call or connect to network endpoint. Make sure to add https://docs.rs/retry/latest/retry/ to your project before proceeding with retry feature.

Retry mechanism is implemented as part of composeable procedureal macro. Below is example of add_10 function configured to be retried 2 times after initial failure.

use retry::delay::*;
#[composeable(retry = Fixed::from_millis(100).take(2))]
pub fn add_10(a: i32) -> Result<i32, String> {
    Ok(a + 10)
}

Retry can be applied to both sync and async functions.

for async functions, all arguments to the function must be either shared reference or exclusive reference.

Below is example of async function with retry.

#[composeable(retry = Fixed::from_millis(100))]
pub fn add_3_arg_ref__non_copy_async<'a>(
    a: &'a mut Vec<String>,
    b: &'a mut Vec<String>,
    c: &'a Vec<String>,
) -> BoxFuture<'a, Result<i32, String>> {
    async move {
        let r = a.len() + b.len() + c.len();
        Ok(r as i32)
    }
    .boxed()
}

Apart from fixed duration retries, it is possible to configure with exponential delay. Refer to retry documentation for all available delay options https://docs.rs/retry/latest/retry/all.html

Modules§

macros

Macros§

compose
concat_idents
This macros makes it possible to concatenate identifiers at compile time and use them as normal. It’s an extension/replacement of std::concat_idents, since in comprassion to the std-solution, the idents here can be used everywhere.
paste

Traits§

Injector
Then
trait Then allows you to compose functions. Type param A represents the function arg of Self

Functions§

lift_async_fn1
Function to box FnOnce sync function with 1 aguments and coerce it to BoxedAsyncFn1
lift_async_fn2
Function to box FnOnce sync function with 2 aguments and coerce it to BoxedAsyncFn2
lift_async_fn3
Function to box FnOnce sync function with 3 aguments and coerce it to BoxedAsyncFn3
lift_async_fn4
Function to box FnOnce sync function with 4 aguments and coerce it to BoxedAsyncFn4
lift_async_fn5
Function to box FnOnce sync function with 5 aguments and coerce it to BoxedAsyncFn5
lift_async_fn6
Function to box FnOnce sync function with 6 aguments and coerce it to BoxedAsyncFn6
lift_async_fn7
Function to box FnOnce sync function with 7 aguments and coerce it to BoxedAsyncFn7
lift_async_fn8
Function to box FnOnce sync function with 8 aguments and coerce it to BoxedAsyncFn8
lift_sync_fn1
Function to box FnOnce sync function with 1 aguments and coerce it to BoxedFn1
lift_sync_fn2
Function to box FnOnce sync function with 2 aguments and coerce it to BoxedFn2
lift_sync_fn3
Function to box FnOnce sync function with 3 aguments and coerce it to BoxedFn3
lift_sync_fn4
Function to box FnOnce sync function with 4 aguments and coerce it to BoxedFn4
lift_sync_fn5
Function to box FnOnce sync function with 5 aguments and coerce it to BoxedFn5
lift_sync_fn6
Function to box FnOnce sync function with 6 aguments and coerce it to BoxedFn6
lift_sync_fn7
Function to box FnOnce sync function with 7 aguments and coerce it to BoxedFn7
lift_sync_fn8
Function to box FnOnce sync function with 8 aguments and coerce it to BoxedFn8
provider_async_f2
dependency injection function provider_async_f2 for injecting the last argument of a given async function
provider_async_f3
dependency injection function provider_async_f3 for injecting the last argument of a given async function
provider_async_f4
dependency injection function provider_async_f4 for injecting the last argument of a given async function
provider_async_f5
dependency injection function provider_async_f5 for injecting the last argument of a given async function
provider_async_f6
dependency injection function provider_async_f6 for injecting the last argument of a given async function
provider_async_f7
dependency injection function provider_async_f7 for injecting the last argument of a given async function
provider_async_f8
dependency injection function provider_async_f8 for injecting the last argument of a given async function
provider_f2
dependency injection function provide_f2 for injecting the last argument of a given sync function
provider_f3
dependency injection function provide_f3 for injecting the last argument of a given sync function
provider_f4
dependency injection function provide_f4 for injecting the last argument of a given sync function
provider_f5
dependency injection function provide_f5 for injecting the last argument of a given sync function
provider_f6
dependency injection function provide_f6 for injecting the last argument of a given sync function
provider_f7
dependency injection function provide_f7 for injecting the last argument of a given sync function
provider_f8
dependency injection function provide_f8 for injecting the last argument of a given sync function

Type Aliases§

BoxedAsyncFn1
Type alias BoxedAsyncFn1 for Boxed FnOnce async function1 arguments
BoxedAsyncFn2
Type alias BoxedAsyncFn2 for Boxed FnOnce async function2 arguments
BoxedAsyncFn3
Type alias BoxedAsyncFn3 for Boxed FnOnce async function3 arguments
BoxedAsyncFn4
Type alias BoxedAsyncFn4 for Boxed FnOnce async function4 arguments
BoxedAsyncFn5
Type alias BoxedAsyncFn5 for Boxed FnOnce async function5 arguments
BoxedAsyncFn6
Type alias BoxedAsyncFn6 for Boxed FnOnce async function6 arguments
BoxedAsyncFn7
Type alias BoxedAsyncFn7 for Boxed FnOnce async function7 arguments
BoxedAsyncFn8
Type alias BoxedAsyncFn8 for Boxed FnOnce async function8 arguments
BoxedFn1
Type alias BoxedFn1 for Boxed FnOnce sync function with 1 arguments
BoxedFn2
Type alias BoxedFn2 for Boxed FnOnce sync function with 2 arguments
BoxedFn3
Type alias BoxedFn3 for Boxed FnOnce sync function with 3 arguments
BoxedFn4
Type alias BoxedFn4 for Boxed FnOnce sync function with 4 arguments
BoxedFn5
Type alias BoxedFn5 for Boxed FnOnce sync function with 5 arguments
BoxedFn6
Type alias BoxedFn6 for Boxed FnOnce sync function with 6 arguments
BoxedFn7
Type alias BoxedFn7 for Boxed FnOnce sync function with 7 arguments
BoxedFn8
Type alias BoxedFn8 for Boxed FnOnce sync function with 8 arguments

Attribute Macros§

composeable
retry