diff --git a/tokio-util/src/codec/length_delimited.rs b/tokio-util/src/codec/length_delimited.rs index de0eb4e9201..93d2f180d0f 100644 --- a/tokio-util/src/codec/length_delimited.rs +++ b/tokio-util/src/codec/length_delimited.rs @@ -84,7 +84,7 @@ //! # fn bind_read(io: T) { //! LengthDelimitedCodec::builder() //! .length_field_offset(0) // default value -//! .length_field_length(2) +//! .length_field_type::() //! .length_adjustment(0) // default value //! .num_skip(0) // Do not strip frame header //! .new_read(io); @@ -118,7 +118,7 @@ //! # fn bind_read(io: T) { //! LengthDelimitedCodec::builder() //! .length_field_offset(0) // default value -//! .length_field_length(2) +//! .length_field_type::() //! .length_adjustment(0) // default value //! // `num_skip` is not needed, the default is to skip //! .new_read(io); @@ -150,7 +150,7 @@ //! # fn bind_read(io: T) { //! LengthDelimitedCodec::builder() //! .length_field_offset(0) // default value -//! .length_field_length(2) +//! .length_field_type::() //! .length_adjustment(-2) // size of head //! .num_skip(0) //! .new_read(io); @@ -228,7 +228,7 @@ //! # fn bind_read(io: T) { //! LengthDelimitedCodec::builder() //! .length_field_offset(1) // length of hdr1 -//! .length_field_length(2) +//! .length_field_type::() //! .length_adjustment(1) // length of hdr2 //! .num_skip(3) // length of hdr1 + LEN //! .new_read(io); @@ -274,7 +274,7 @@ //! # fn bind_read(io: T) { //! LengthDelimitedCodec::builder() //! .length_field_offset(1) // length of hdr1 -//! .length_field_length(2) +//! .length_field_type::() //! .length_adjustment(-3) // length of hdr1 + LEN, negative //! .num_skip(3) //! .new_read(io); @@ -350,7 +350,7 @@ //! # fn write_frame(io: T) { //! # let _ = //! LengthDelimitedCodec::builder() -//! .length_field_length(2) +//! .length_field_type::() //! .new_write(io); //! # } //! # pub fn main() {} @@ -379,7 +379,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use bytes::{Buf, BufMut, Bytes, BytesMut}; use std::error::Error as StdError; use std::io::{self, Cursor}; -use std::{cmp, fmt}; +use std::{cmp, fmt, mem}; /// Configure length delimited `LengthDelimitedCodec`s. /// @@ -629,6 +629,24 @@ impl Default for LengthDelimitedCodec { // ===== 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 { /// Creates a new length delimited codec builder with default configuration /// values. @@ -642,7 +660,7 @@ impl Builder { /// # fn bind_read(io: T) { /// LengthDelimitedCodec::builder() /// .length_field_offset(0) - /// .length_field_length(2) + /// .length_field_type::() /// .length_adjustment(0) /// .num_skip(0) /// .new_read(io); @@ -777,6 +795,42 @@ impl Builder { 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(io: T) { + /// LengthDelimitedCodec::builder() + /// .length_field_type::() + /// .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(io: T) { + /// LengthDelimitedCodec::builder() + /// .length_field_type::() + /// .new_read(io); + /// # } + /// # pub fn main() {} + /// ``` + pub fn length_field_type(&mut self) -> &mut Self { + self.length_field_length(mem::size_of::()) + } + /// Sets the number of bytes used to represent the length field /// /// The default value is `4`. The max value is `8`. @@ -878,7 +932,7 @@ impl Builder { /// # pub fn main() { /// LengthDelimitedCodec::builder() /// .length_field_offset(0) - /// .length_field_length(2) + /// .length_field_type::() /// .length_adjustment(0) /// .num_skip(0) /// .new_codec(); @@ -902,7 +956,7 @@ impl Builder { /// # fn bind_read(io: T) { /// LengthDelimitedCodec::builder() /// .length_field_offset(0) - /// .length_field_length(2) + /// .length_field_type::() /// .length_adjustment(0) /// .num_skip(0) /// .new_read(io); @@ -925,7 +979,7 @@ impl Builder { /// # use tokio_util::codec::LengthDelimitedCodec; /// # fn write_frame(io: T) { /// LengthDelimitedCodec::builder() - /// .length_field_length(2) + /// .length_field_type::() /// .new_write(io); /// # } /// # pub fn main() {} @@ -947,7 +1001,7 @@ impl Builder { /// # fn write_frame(io: T) { /// # let _ = /// LengthDelimitedCodec::builder() - /// .length_field_length(2) + /// .length_field_type::() /// .new_framed(io); /// # } /// # pub fn main() {}