codec: fix length_delimited docs examples (#6638)

This commit is contained in:
Hai-Hsin 2024-06-23 12:52:51 +08:00 committed by GitHub
parent ed4ddf443d
commit 06582776a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -75,55 +75,23 @@
//!
//! ## Example 1
//!
//! The following will parse a `u16` length field at offset 0, including the
//! frame head in the yielded `BytesMut`.
//!
//! ```
//! # use tokio::io::AsyncRead;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value
//! .length_field_type::<u16>()
//! .length_adjustment(0) // default value
//! .num_skip(0) // Do not strip frame header
//! .new_read(io);
//! # }
//! # pub fn main() {}
//! ```
//!
//! The following frame will be decoded as such:
//!
//! ```text
//! INPUT DECODED
//! +-- len ---+--- Payload ---+ +-- len ---+--- Payload ---+
//! | \x00\x0B | Hello world | --> | \x00\x0B | Hello world |
//! +----------+---------------+ +----------+---------------+
//! ```
//!
//! The value of the length field is 11 (`\x0B`) which represents the length
//! of the payload, `hello world`. By default, [`FramedRead`] assumes that
//! the length field represents the number of bytes that **follows** the
//! length field. Thus, the entire frame has a length of 13: 2 bytes for the
//! frame head + 11 bytes for the payload.
//!
//! ## Example 2
//!
//! The following will parse a `u16` length field at offset 0, omitting the
//! frame head in the yielded `BytesMut`.
//!
//! ```
//! # use tokio::io::AsyncRead;
//! # use tokio_stream::StreamExt;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder()
//! # #[tokio::main]
//! # async fn main() {
//! # let io: &[u8] = b"\x00\x0BHello world";
//! let mut reader = LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value
//! .length_field_type::<u16>()
//! .length_adjustment(0) // default value
//! // `num_skip` is not needed, the default is to skip
//! .new_read(io);
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
//! # assert_eq!(res, b"Hello world");
//! # }
//! # pub fn main() {}
//! ```
//!
//! The following frame will be decoded as such:
@ -135,27 +103,32 @@
//! +----------+---------------+ +---------------+
//! ```
//!
//! This is similar to the first example, the only difference is that the
//! frame head is **not** included in the yielded `BytesMut` value.
//! The value of the length field is 11 (`\x0B`) which represents the length
//! of the payload, `hello world`. By default, [`FramedRead`] assumes that
//! the length field represents the number of bytes that **follows** the
//! length field. Thus, the entire frame has a length of 13: 2 bytes for the
//! frame head + 11 bytes for the payload.
//!
//! ## Example 3
//! ## Example 2
//!
//! The following will parse a `u16` length field at offset 0, including the
//! frame head in the yielded `BytesMut`. In this case, the length field
//! **includes** the frame head length.
//! frame head in the yielded `BytesMut`.
//!
//! ```
//! # use tokio::io::AsyncRead;
//! # use tokio_stream::StreamExt;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder()
//! # #[tokio::main]
//! # async fn main() {
//! # let io: &[u8] = b"\x00\x0BHello world";
//! let mut reader = LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value
//! .length_field_type::<u16>()
//! .length_adjustment(-2) // size of head
//! .num_skip(0)
//! .length_adjustment(2) // Add head size to length
//! .num_skip(0) // Do NOT skip the head
//! .new_read(io);
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
//! # assert_eq!(res, b"\x00\x0BHello world");
//! # }
//! # pub fn main() {}
//! ```
//!
//! The following frame will be decoded as such:
@ -163,10 +136,46 @@
//! ```text
//! INPUT DECODED
//! +-- len ---+--- Payload ---+ +-- len ---+--- Payload ---+
//! | \x00\x0D | Hello world | --> | \x00\x0D | Hello world |
//! | \x00\x0B | Hello world | --> | \x00\x0B | Hello world |
//! +----------+---------------+ +----------+---------------+
//! ```
//!
//! This is similar to the first example, the only difference is that the
//! frame head is **included** in the yielded `BytesMut` value. To achieve
//! this, we need to add the header size to the length with `length_adjustment`,
//! and set `num_skip` to `0` to prevent skipping the head.
//!
//! ## Example 3
//!
//! The following will parse a `u16` length field at offset 0, omitting the
//! frame head in the yielded `BytesMut`. In this case, the length field
//! **includes** the frame head length.
//!
//! ```
//! # use tokio_stream::StreamExt;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # #[tokio::main]
//! # async fn main() {
//! # let io: &[u8] = b"\x00\x0DHello world";
//! let mut reader = LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value
//! .length_field_type::<u16>()
//! .length_adjustment(-2) // size of head
//! .new_read(io);
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
//! # assert_eq!(res, b"Hello world");
//! # }
//! ```
//!
//! The following frame will be decoded as such:
//!
//! ```text
//! INPUT DECODED
//! +-- len ---+--- Payload ---+ +--- Payload ---+
//! | \x00\x0D | Hello world | --> | Hello world |
//! +----------+---------------+ +---------------+
//! ```
//!
//! In most cases, the length field represents the length of the payload
//! only, as shown in the previous examples. However, in some protocols the
//! length field represents the length of the whole frame, including the
@ -179,17 +188,20 @@
//! frame head, including the frame head in the yielded `BytesMut`.
//!
//! ```
//! # use tokio::io::AsyncRead;
//! # use tokio_stream::StreamExt;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder()
//! # #[tokio::main]
//! # async fn main() {
//! # let io: &[u8] = b"\x00\x00\x0B\xCA\xFEHello world";
//! let mut reader = LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value
//! .length_field_length(3)
//! .length_adjustment(2) // remaining head
//! .length_adjustment(3 + 2) // len field and remaining head
//! .num_skip(0)
//! .new_read(io);
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
//! # assert_eq!(res, b"\x00\x00\x0B\xCA\xFEHello world");
//! # }
//! # pub fn main() {}
//! ```
//!
//! The following frame will be decoded as such:
@ -223,17 +235,20 @@
//! included.
//!
//! ```
//! # use tokio::io::AsyncRead;
//! # use tokio_stream::StreamExt;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder()
//! # #[tokio::main]
//! # async fn main() {
//! # let io: &[u8] = b"\xCA\x00\x0B\xFEHello world";
//! let mut reader = LengthDelimitedCodec::builder()
//! .length_field_offset(1) // length of hdr1
//! .length_field_type::<u16>()
//! .length_adjustment(1) // length of hdr2
//! .num_skip(3) // length of hdr1 + LEN
//! .new_read(io);
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
//! # assert_eq!(res, b"\xFEHello world");
//! # }
//! # pub fn main() {}
//! ```
//!
//! The following frame will be decoded as such:
@ -269,15 +284,19 @@
//! length.
//!
//! ```
//! # use tokio::io::AsyncRead;
//! # use tokio_stream::StreamExt;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder()
//! # #[tokio::main]
//! # async fn main() {
//! # let io: &[u8] = b"\xCA\x00\x0F\xFEHello world";
//! let mut reader = LengthDelimitedCodec::builder()
//! .length_field_offset(1) // length of hdr1
//! .length_field_type::<u16>()
//! .length_adjustment(-3) // length of hdr1 + LEN, negative
//! .num_skip(3)
//! .new_read(io);
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
//! # assert_eq!(res, b"\xFEHello world");
//! # }
//! ```
//!
@ -308,17 +327,20 @@
//! frame head, excluding the 4th byte from the yielded `BytesMut`.
//!
//! ```
//! # use tokio::io::AsyncRead;
//! # use tokio_stream::StreamExt;
//! # use tokio_util::codec::LengthDelimitedCodec;
//! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder()
//! # #[tokio::main]
//! # async fn main() {
//! # let io: &[u8] = b"\x00\x00\x0B\xFFHello world";
//! let mut reader = LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value
//! .length_field_length(3)
//! .length_adjustment(0) // default value
//! .num_skip(4) // skip the first 4 bytes
//! .new_read(io);
//! # let res = reader.next().await.unwrap().unwrap().to_vec();
//! # assert_eq!(res, b"Hello world");
//! # }
//! # pub fn main() {}
//! ```
//!
//! The following frame will be decoded as such: