codec: add length_field_type to LengthDelimitedCodec builder (#4508)

This commit is contained in:
Nikolai Vazquez
2022-02-23 11:46:52 +01:00
committed by GitHub
parent 503ae34cd3
commit 3f508d1622
+66 -12
View File
@@ -84,7 +84,7 @@
//! # fn bind_read<T: AsyncRead>(io: T) { //! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder() //! LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value //! .length_field_offset(0) // default value
//! .length_field_length(2) //! .length_field_type::<u16>()
//! .length_adjustment(0) // default value //! .length_adjustment(0) // default value
//! .num_skip(0) // Do not strip frame header //! .num_skip(0) // Do not strip frame header
//! .new_read(io); //! .new_read(io);
@@ -118,7 +118,7 @@
//! # fn bind_read<T: AsyncRead>(io: T) { //! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder() //! LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value //! .length_field_offset(0) // default value
//! .length_field_length(2) //! .length_field_type::<u16>()
//! .length_adjustment(0) // default value //! .length_adjustment(0) // default value
//! // `num_skip` is not needed, the default is to skip //! // `num_skip` is not needed, the default is to skip
//! .new_read(io); //! .new_read(io);
@@ -150,7 +150,7 @@
//! # fn bind_read<T: AsyncRead>(io: T) { //! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder() //! LengthDelimitedCodec::builder()
//! .length_field_offset(0) // default value //! .length_field_offset(0) // default value
//! .length_field_length(2) //! .length_field_type::<u16>()
//! .length_adjustment(-2) // size of head //! .length_adjustment(-2) // size of head
//! .num_skip(0) //! .num_skip(0)
//! .new_read(io); //! .new_read(io);
@@ -228,7 +228,7 @@
//! # fn bind_read<T: AsyncRead>(io: T) { //! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder() //! LengthDelimitedCodec::builder()
//! .length_field_offset(1) // length of hdr1 //! .length_field_offset(1) // length of hdr1
//! .length_field_length(2) //! .length_field_type::<u16>()
//! .length_adjustment(1) // length of hdr2 //! .length_adjustment(1) // length of hdr2
//! .num_skip(3) // length of hdr1 + LEN //! .num_skip(3) // length of hdr1 + LEN
//! .new_read(io); //! .new_read(io);
@@ -274,7 +274,7 @@
//! # fn bind_read<T: AsyncRead>(io: T) { //! # fn bind_read<T: AsyncRead>(io: T) {
//! LengthDelimitedCodec::builder() //! LengthDelimitedCodec::builder()
//! .length_field_offset(1) // length of hdr1 //! .length_field_offset(1) // length of hdr1
//! .length_field_length(2) //! .length_field_type::<u16>()
//! .length_adjustment(-3) // length of hdr1 + LEN, negative //! .length_adjustment(-3) // length of hdr1 + LEN, negative
//! .num_skip(3) //! .num_skip(3)
//! .new_read(io); //! .new_read(io);
@@ -350,7 +350,7 @@
//! # fn write_frame<T: AsyncWrite>(io: T) { //! # fn write_frame<T: AsyncWrite>(io: T) {
//! # let _ = //! # let _ =
//! LengthDelimitedCodec::builder() //! LengthDelimitedCodec::builder()
//! .length_field_length(2) //! .length_field_type::<u16>()
//! .new_write(io); //! .new_write(io);
//! # } //! # }
//! # pub fn main() {} //! # pub fn main() {}
@@ -379,7 +379,7 @@ use tokio::io::{AsyncRead, AsyncWrite};
use bytes::{Buf, BufMut, Bytes, BytesMut}; use bytes::{Buf, BufMut, Bytes, BytesMut};
use std::error::Error as StdError; use std::error::Error as StdError;
use std::io::{self, Cursor}; use std::io::{self, Cursor};
use std::{cmp, fmt}; use std::{cmp, fmt, mem};
/// Configure length delimited `LengthDelimitedCodec`s. /// Configure length delimited `LengthDelimitedCodec`s.
/// ///
@@ -629,6 +629,24 @@ impl Default for LengthDelimitedCodec {
// ===== impl Builder ===== // ===== impl Builder =====
mod builder {
/// Types that can be used with `Builder::length_field_type`.
pub trait LengthFieldType {}
impl LengthFieldType for u8 {}
impl LengthFieldType for u16 {}
impl LengthFieldType for u32 {}
impl LengthFieldType for u64 {}
#[cfg(any(
target_pointer_width = "8",
target_pointer_width = "16",
target_pointer_width = "32",
target_pointer_width = "64",
))]
impl LengthFieldType for usize {}
}
impl Builder { impl Builder {
/// Creates a new length delimited codec builder with default configuration /// Creates a new length delimited codec builder with default configuration
/// values. /// values.
@@ -642,7 +660,7 @@ impl Builder {
/// # fn bind_read<T: AsyncRead>(io: T) { /// # fn bind_read<T: AsyncRead>(io: T) {
/// LengthDelimitedCodec::builder() /// LengthDelimitedCodec::builder()
/// .length_field_offset(0) /// .length_field_offset(0)
/// .length_field_length(2) /// .length_field_type::<u16>()
/// .length_adjustment(0) /// .length_adjustment(0)
/// .num_skip(0) /// .num_skip(0)
/// .new_read(io); /// .new_read(io);
@@ -777,6 +795,42 @@ impl Builder {
self self
} }
/// Sets the unsigned integer type used to represent the length field.
///
/// The default type is [`u32`]. The max type is [`u64`] (or [`usize`] on
/// 64-bit targets).
///
/// # Examples
///
/// ```
/// # use tokio::io::AsyncRead;
/// use tokio_util::codec::LengthDelimitedCodec;
///
/// # fn bind_read<T: AsyncRead>(io: T) {
/// LengthDelimitedCodec::builder()
/// .length_field_type::<u32>()
/// .new_read(io);
/// # }
/// # pub fn main() {}
/// ```
///
/// Unlike [`Builder::length_field_length`], this does not fail at runtime
/// and instead produces a compile error:
///
/// ```compile_fail
/// # use tokio::io::AsyncRead;
/// # use tokio_util::codec::LengthDelimitedCodec;
/// # fn bind_read<T: AsyncRead>(io: T) {
/// LengthDelimitedCodec::builder()
/// .length_field_type::<u128>()
/// .new_read(io);
/// # }
/// # pub fn main() {}
/// ```
pub fn length_field_type<T: builder::LengthFieldType>(&mut self) -> &mut Self {
self.length_field_length(mem::size_of::<T>())
}
/// Sets the number of bytes used to represent the length field /// Sets the number of bytes used to represent the length field
/// ///
/// The default value is `4`. The max value is `8`. /// The default value is `4`. The max value is `8`.
@@ -878,7 +932,7 @@ impl Builder {
/// # pub fn main() { /// # pub fn main() {
/// LengthDelimitedCodec::builder() /// LengthDelimitedCodec::builder()
/// .length_field_offset(0) /// .length_field_offset(0)
/// .length_field_length(2) /// .length_field_type::<u16>()
/// .length_adjustment(0) /// .length_adjustment(0)
/// .num_skip(0) /// .num_skip(0)
/// .new_codec(); /// .new_codec();
@@ -902,7 +956,7 @@ impl Builder {
/// # fn bind_read<T: AsyncRead>(io: T) { /// # fn bind_read<T: AsyncRead>(io: T) {
/// LengthDelimitedCodec::builder() /// LengthDelimitedCodec::builder()
/// .length_field_offset(0) /// .length_field_offset(0)
/// .length_field_length(2) /// .length_field_type::<u16>()
/// .length_adjustment(0) /// .length_adjustment(0)
/// .num_skip(0) /// .num_skip(0)
/// .new_read(io); /// .new_read(io);
@@ -925,7 +979,7 @@ impl Builder {
/// # use tokio_util::codec::LengthDelimitedCodec; /// # use tokio_util::codec::LengthDelimitedCodec;
/// # fn write_frame<T: AsyncWrite>(io: T) { /// # fn write_frame<T: AsyncWrite>(io: T) {
/// LengthDelimitedCodec::builder() /// LengthDelimitedCodec::builder()
/// .length_field_length(2) /// .length_field_type::<u16>()
/// .new_write(io); /// .new_write(io);
/// # } /// # }
/// # pub fn main() {} /// # pub fn main() {}
@@ -947,7 +1001,7 @@ impl Builder {
/// # fn write_frame<T: AsyncRead + AsyncWrite>(io: T) { /// # fn write_frame<T: AsyncRead + AsyncWrite>(io: T) {
/// # let _ = /// # let _ =
/// LengthDelimitedCodec::builder() /// LengthDelimitedCodec::builder()
/// .length_field_length(2) /// .length_field_type::<u16>()
/// .new_framed(io); /// .new_framed(io);
/// # } /// # }
/// # pub fn main() {} /// # pub fn main() {}