# Handlers
rs-netty 有五类 stage trait。它们都在 `src/traits.rs`,并通过 `trait-variant` 生成 `Send` 版本作为公开主接口。
## Inbound
`Inbound<I>` 用于解码后、final handler 前的入站转换:
```rust
struct Trim;
impl Inbound<String> for Trim {
type Out = String;
async fn read(
&mut self,
_ctx: &mut rs_netty::InboundContext,
msg: String,
) -> rs_netty::Result<rs_netty::Flow<Self::Out>> {
Ok(rs_netty::Flow::Next(msg.trim().to_string()))
}
}
```
`InboundContext` 暴露 `id()`、`peer_addr()`、`local_addr()`,不提供写能力。
## Business
`Business<I>` 是 inbound 和 final handler 之间的应用级转换阶段。它和 `Inbound` 的类型形状类似,但方法名是 `handle`,context 是 `BusinessContext`。builder 限制是:进入 business 后只能继续加 business 或 final handler,不能再回到 inbound。
## Handler
`Handler<I>` 是 TCP inbound side 的终点:
```rust
impl Handler<Request> for Router {
type Write = Response;
async fn read(&mut self, ctx: &mut Context<Self::Write>, req: Request) -> Result<()> {
ctx.write_and_flush(Response { body: req.body }).await
}
}
```
`type Write` 是 handler 能写回 outbound side 的应用类型。后续 outbound stage 会从这个类型开始转换,最终转成 codec 可编码的类型。
`Context<W>` 提供:
- identity: `id`、`peer_addr`、`local_addr`
- `channel()`:cloneable external channel
- `stats()`:启用 stats 时返回 `ConnectionStats`
- `write`、`flush`、`write_and_flush`
- `close`
## DatagramHandler
`DatagramHandler<I>` 是 UDP inbound side 的终点。它使用 `DatagramContext<W>`,支持 `write`、`write_to`、`flush`、`write_and_flush`、`write_to_and_flush` 和 `close`。
```rust
impl DatagramHandler<String> for UdpEcho {
type Write = String;
async fn read(&mut self, ctx: &mut DatagramContext<Self::Write>, msg: String) -> Result<()> {
ctx.write_and_flush(format!("echo: {msg}")).await
}
}
```
## Outbound
`Outbound<I>` 用于把 handler 写出的应用类型渲染成下游 outbound 类型。最终 outbound 类型必须由 codec encode。
```rust
struct RenderResponse;
impl Outbound<Response> for RenderResponse {
type Out = String;
async fn write(
&mut self,
_ctx: &mut rs_netty::OutboundContext,
msg: Response,
) -> rs_netty::Result<rs_netty::Flow<Self::Out>> {
Ok(rs_netty::Flow::Next(msg.body))
}
}
```
`OutboundContext` 同样只暴露 identity,不提供直接写能力。
## Macro Or Manual Impl
`#[handler]` 适合一进一出的简单 final handler,或者 consume-only handler。需要直接访问 `Context` / `DatagramContext`、控制 flush timing、多次写入、关闭连接或拿 `channel()` 时,写手动 impl 更清晰。