rs-netty 1.1.0

A Tokio-native typed TCP/UDP pipeline framework inspired by Netty.
Documentation
# Design Goals

rs-netty 的设计目标不是把 Java Netty 原样搬到 Rust,而是把 pipeline/handler/channel 这套建模方式换成 Rust-native 的形式。

## Keep The Useful Shape

保留的概念:

- codec 位于 pipeline 边界,负责 bytes/datagrams 和 typed message 之间的转换。
- inbound stage 处理解码后的入站消息。
- final handler 处理应用语义,并写出应用层响应。
- outbound stage 把 handler 写出的应用类型转换成 codec 可编码类型。
- channel handle 可以从当前 handler 外部写入、flush 或关闭连接。
- lifecycle hook 可以观察 server、connection 和 UDP socket 的启动/关闭。

## Use Rust Types Instead Of Dynamic Pipeline Mutation

Java Netty 的动态 pipeline 很灵活,但错误通常在运行时出现:handler 顺序不对、上游消息类型与下游不匹配、TCP pipeline 被误用于 UDP 等。rs-netty 把这些约束编码在 builder 类型里:

```text
codec -> inbound* -> business* -> handler -> outbound*
```

只有当前状态允许的方法才存在。比如在 `.codec(...)` 之前没有 `.handler(...)`,在 `.handler(...)` 之后没有 `.inbound(...)`,并且最终 outbound 类型必须被 codec 的 encoder 支持。

仓库里的 trybuild 用例覆盖了这些失败场景,例如:

- `fail_stream_handler_before_codec.rs`
- `fail_stream_outbound_before_handler.rs`
- `fail_stream_type_mismatch_inbound_to_handler.rs`
- `fail_stream_final_encoder_mismatch.rs`
- `fail_udp_with_stream_pipeline.rs`
- `fail_tcp_with_datagram_pipeline.rs`

## Separate TCP And UDP Builders

TCP 使用 `pipeline()`,要求 codec 实现 `Decoder` 和 `Encoder<T>`。UDP 使用 `datagram_pipeline()`,要求 codec 实现 `DatagramDecoder` 和 `DatagramEncoder<T>`。

这不是命名偏好,而是类型边界。`TcpServer::pipeline` 只接受 `IntoStreamPipeline`,`UdpServer::pipeline` 只接受 `IntoDatagramPipeline`。因此 TCP/UDP pipeline 混用不会通过编译。

## Prefer Owned Messages

框架没有暴露 Java Netty 风格的 reference-counted `ByteBuf`。codec 和 handler 在公开 API 中使用 `String`、`bytes::Bytes`、用户自定义 struct 等 owned 类型。这样更贴近 Rust 的所有权模型,也减少了 refCnt 误用带来的生命周期风险。

## Bounded Queues And Explicit Flush

`Channel` 和 `DatagramChannel` 背后使用 bounded Tokio `mpsc`。`outbound_queue_size` 控制外部写入命令队列大小;队列满时写调用等待容量,而不是无限制堆积。

写入和 flush 明确分离:

- `write` 只排队或暂存。
- `flush` 推送已暂存数据到 socket。
- `write_and_flush` 写入并建立一个 flush 边界。

这个模型让高吞吐场景可以 batch,也让低延迟场景可以显式 flush。

## Zero Unsafe

crate 根使用 `#![deny(unsafe_code)]`,`rs-netty-macros` 也启用了同样的约束。当前主库和宏库都不依赖 `unsafe` 作为实现主路径。