diff --git a/benches/write.rs b/benches/write.rs index 573fe944..cf7ab7e6 100644 --- a/benches/write.rs +++ b/benches/write.rs @@ -1,8 +1,6 @@ //! Benchmarks for write performance. -use bytes::{BufMut, BytesMut}; use criterion::Criterion; use std::{ - fmt::Write as _, hint, io, time::{Duration, Instant}, }; @@ -55,19 +53,11 @@ fn benchmark(c: &mut Criterion) { let mut ws = WebSocket::from_raw_socket(MockWrite(Vec::with_capacity(MOCK_WRITE_LEN)), role, None); - let mut buf = BytesMut::with_capacity(128 * 1024); - b.iter(|| { for i in 0_u64..100_000 { let msg = match i { - _ if i % 3 == 0 => { - buf.put_slice(&i.to_le_bytes()); - Message::binary(buf.split()) - } - _ => { - buf.write_fmt(format_args!("{{\"id\":{i}}}")).unwrap(); - Message::Text(buf.split().try_into().unwrap()) - } + _ if i % 3 == 0 => Message::binary(i.to_le_bytes().to_vec()), + _ => Message::text(format!("{{\"id\":{i}}}")), }; ws.write(msg).unwrap(); } diff --git a/src/protocol/frame/frame.rs b/src/protocol/frame/frame.rs index 3a9ff515..ef8dfe3c 100644 --- a/src/protocol/frame/frame.rs +++ b/src/protocol/frame/frame.rs @@ -304,7 +304,7 @@ impl Frame { 0 => Ok(None), 1 => Err(Error::Protocol(ProtocolError::InvalidCloseSequence)), _ => { - let mut data = self.payload.into_data(); + let mut data = self.payload.as_slice(); let code = u16::from_be_bytes([data[0], data[1]]).into(); data.advance(2); let text = String::from_utf8(data.to_vec())?; diff --git a/src/protocol/frame/mod.rs b/src/protocol/frame/mod.rs index 76baeae7..8b508047 100644 --- a/src/protocol/frame/mod.rs +++ b/src/protocol/frame/mod.rs @@ -121,7 +121,7 @@ impl FrameCodec { pub(super) fn new() -> Self { Self { in_buffer: BytesMut::with_capacity(READ_BUFFER_CAP), - out_buffer: Vec::new(), + out_buffer: <_>::default(), max_out_buffer_len: usize::MAX, out_buffer_write_len: 0, header: None, @@ -134,7 +134,7 @@ impl FrameCodec { in_buffer.reserve(READ_BUFFER_CAP.saturating_sub(in_buffer.len())); Self { in_buffer, - out_buffer: Vec::new(), + out_buffer: <_>::default(), max_out_buffer_len: usize::MAX, out_buffer_write_len: 0, header: None, diff --git a/src/protocol/frame/payload.rs b/src/protocol/frame/payload.rs index eb7a5a29..63add2bb 100644 --- a/src/protocol/frame/payload.rs +++ b/src/protocol/frame/payload.rs @@ -63,6 +63,15 @@ impl TryFrom for Utf8Payload { } } +impl TryFrom> for Utf8Payload { + type Error = str::Utf8Error; + + #[inline] + fn try_from(bytes: Vec) -> Result { + Payload::from(bytes).try_into() + } +} + impl From for Utf8Payload { #[inline] fn from(s: String) -> Self { @@ -104,6 +113,8 @@ pub enum Payload { Owned(BytesMut), /// Shared data with shared ownership. Shared(Bytes), + /// Owned vec data. + Vec(Vec), } impl Payload { @@ -135,6 +146,7 @@ impl Payload { match self { Payload::Owned(v) => v, Payload::Shared(v) => v, + Payload::Vec(v) => v, } } @@ -148,6 +160,7 @@ impl Payload { pub fn as_mut_slice(&mut self) -> &mut [u8] { match self { Payload::Owned(v) => &mut *v, + Payload::Vec(v) => &mut *v, Payload::Shared(v) => { // Using `Bytes::to_vec()` or `Vec::from(bytes.as_ref())` would mean making a copy. // `Bytes::into()` would not make a copy if our `Bytes` instance is the only one. @@ -155,7 +168,7 @@ impl Payload { *self = Payload::Owned(data); match self { Payload::Owned(v) => v, - Payload::Shared(_) => unreachable!(), + _ => unreachable!(), } } } @@ -163,18 +176,14 @@ impl Payload { /// Returns the length of the payload. #[inline] - #[allow(clippy::len_without_is_empty)] pub fn len(&self) -> usize { self.as_slice().len() } - /// Consumes the payload and returns the underlying data as a vector. + /// Returns true if the payload has a length of 0. #[inline] - pub fn into_data(self) -> BytesMut { - match self { - Payload::Owned(v) => v, - Payload::Shared(v) => v.into(), - } + pub fn is_empty(&self) -> bool { + self.len() == 0 } /// Consumes the payload and returns the underlying data as a string. @@ -194,14 +203,14 @@ impl Default for Payload { impl From> for Payload { #[inline] fn from(v: Vec) -> Self { - Payload::Owned(BytesMut::from_iter(v)) + Payload::Vec(v) } } impl From for Payload { #[inline] fn from(v: String) -> Self { - Vec::from(v).into() + v.into_bytes().into() } }