3 个不稳定版本

0.2.0 2024 年 5 月 13 日
0.1.1 2024 年 5 月 12 日
0.1.0 2024 年 5 月 12 日

#2 in #handling

MIT 许可证

35KB
891 行代码(不含注释)

赛纳

可组合处理器的库。许多事情可以用以下方式表达

  1. 接收事件
  2. 处理事件
  3. 回复有意义的内容

sena 是一个库,简化了这种模式下的代码编写,例如

use std::num::ParseIntError;
use sena::handling::Handler;

fn increment<E>() -> impl Handler<i32, E, Output = i32> {
  |req: i32| async move {
    Ok(req + 1)
  }
}

fn parse_int<E: From<ParseIntError>>() -> impl Handler<String, E, Output = i32> {
  |req: String| async move { req.parse().map_err(Into::into) }
}

async fn entrypoint() -> Result<(), ParseIntError> {
  let chain = parse_int::<ParseIntError>() // parses input string
    .pipe(increment())  // pipes output from parse_int to increment
    .pipe(increment()); // one more time
  let result = chain.handle("100".to_owned()).await?;

  assert_eq!(result, 102);
  Ok(())
}

让我们将这段代码分解成几个部分

  1. 首先,我们定义一个处理器,处理器可以是普通函数、闭包或任何实现了 handling::Handler 特性的类型
  2. parse_int 是一个将 String 转换为 i32 的处理器
  3. 处理器上的 .pipe 方法将左侧处理器(点号之前)的输入传递到右侧处理器(在我们的例子中是 increment()
  4. 然后,我们在结果处理器上调用 chain.handle

还有更多用于组合的处理器,如允许在处理器上运行 "中间件"(具有延续的函数)的 handling::seq::Seq 处理器,或者允许将处理器输入转换为其他类型的 handling::map::MapAsync/handling::map::Map 处理器。

还可以查看 [code]csp[/code] 模块和 handling::server::Server,这可以将您的处理器转换为服务器或 "actor"。

依赖注入

sena 并不提供依赖注入的电池,然而,它提供了 handling::Handler::providedependent::Dependent 来满足基本的依赖注入需求,这些对于大量的使用场景来说是足够的。

为什么错误类型是泛型的?

这是一个很好的解决方案,因为它允许以更灵活的方式使用处理器:只要特定的错误可以被转换为那种类型,处理器就可以与任何错误类型一起使用。

示例

查看github: https://github.com/nerodono/sena-rs

依赖项

~2–3MB
~47K SLoC