4 个版本
新版本 0.2.0 | 2024 年 8 月 22 日 |
---|---|
0.1.2 | 2024 年 6 月 27 日 |
0.1.1 | 2024 年 6 月 27 日 |
0.1.0 | 2024 年 6 月 27 日 |
701 在 Rust 模式
28KB
307 行
function-compose
function-compose 是一个函数组合库,允许组合异步和同步函数
fn-composer 函数组合需要两个宏。
过程属性宏 - 可组合
声明性宏 - 组合!
过程属性宏可组合添加到任何可以组合的函数上。例如以下是一个简单的将 10 加到给定数字上的函数。
#[composeable()]
pub fn add_10(a: i32) -> Result<i32, String> {
Ok(a + 10)
}
以下是一个异步示例。异步函数应返回 BoxFuture。
#[composeable()]
pub fn add_async(a: i32, b: i32) -> BoxFuture<'static, Result<i32, String>> {
async move {
let r = a + b;
Ok(r)
}.boxed()
}
以下是一个异步乘法和异步加 100 到一个数字的示例
#[composeable()]
pub fn multiply_async(a: i32, b: i32) -> BoxFuture<'static, Result<i32, String>> {
async move {
let r = a * b;
Ok(r)
}.boxed()
}
#[composeable()]
pub fn add_100_async(a: i32) -> BoxFuture<'static, Result<i32, String>> {
async move {
let r = a + 100;
Ok(r)
}.boxed()
}
以下是一个异步加 3 个值的示例
#[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()
}
以下是一个异步加 3 个值,最后一个参数接受引用的示例
#[composeable()]
pub fn add_3_arg_ref_async<'a>(a: i32,b: &'a i32, c:&'a i32) -> BoxFuture<'a, Result<i32, String>>{
async move{
let r = a + b + c;
Ok(r)
}.boxed()
}
可以将单个参数的同步函数与两个参数的异步函数组合,反之亦然。
以下是如何组合异步函数的示例
let result = compose!(add_10 -> add_100 -> with_args(10));
let result = compose!(add_10 -> add_100 -> add_10 -> add_100 -> with_args(10));
以下是如何组合异步和同步函数的示例
let result = compose!(add_100_async -> add_100 -> with_args(10)).await;
assert_eq!(210, result.unwrap());
let result = compose!(add_100_async -> add_100_async -> with_args(10)).await;
assert_eq!(210, result.unwrap());
可以使用 .provide
方法注入异步函数的第二个参数。这可以用于注入数据库连接或其他外部服务交互。请参阅以下示例
// Check the '.provide' method below of injecting second args to add_async function
let result = compose!(add_async.provide(100) -> add_100_async -> with_args(10)).await;
assert_eq!(210, result.unwrap());
多个注入到异步函数的示例
let result = compose!(add_3_arg_async.provide(100).provide(200) -> add_100_async -> with_args(10)).await;
assert_eq!(410, result.unwrap());
第二个位置注入到异步函数的示例
let result = compose!(add_100 -> add_3_arg_async.provide(1).provide(1) -> with_args(10)).await;
assert_eq!(112, result.unwrap());
共享引用到异步函数的多个注入示例
let one = &1;
let result = compose!(add_3_arg_ref_async.provide(one).provide(one) -> add_3_arg_async.provide(1).provide(1) -> with_args(10)).await;
assert_eq!(14, result.unwrap());
在 Fn Composer 中重试
可组合宏支持在函数返回错误时在指定间隔内重试函数。这在尝试进行数据库调用或连接到网络端点时可能很有用。在进行重试功能之前,请确保安装https://docs.rs/retry/latest/retry/。
重试机制作为可组合过程宏的一部分实现。以下是一个配置为在初始失败后重试 2 次的 add_10 函数的示例。
use retry::delay::*;
#[composeable(retry = Fixed::from_millis(100).take(2))]
pub fn add_10(a: i32) -> Result<i32, String> {
Ok(a + 10)
}
重试可以应用于同步和异步函数。
对于异步函数,函数的所有参数必须是共享引用或独占引用。
以下是带有重试功能的异步函数示例。
#[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()
}
除了固定持续时间重试外,还可以配置指数延迟。有关所有可用的延迟选项,请参阅重试文档 https://docs.rs/retry/latest/retry/all.html
依赖项
~3–5MB
~84K SLoC