diff --git a/ntex-bytes/CHANGELOG.md b/ntex-bytes/CHANGELOG.md index 717d1843..63db3bc5 100644 --- a/ntex-bytes/CHANGELOG.md +++ b/ntex-bytes/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes +## [0.1.22] (2024-01-16) + +* Use const generics for helper traits (From, PartialEq, PartialOrd) + ## [0.1.21] (2023-11-1) * Data race in BytesMut #243 diff --git a/ntex-bytes/Cargo.toml b/ntex-bytes/Cargo.toml index b074535b..077e0288 100644 --- a/ntex-bytes/Cargo.toml +++ b/ntex-bytes/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ntex-bytes" -version = "0.1.21" +version = "0.1.22" authors = ["Nikolay Kim ", "Carl Lerche "] description = "Types and traits for working with bytes (bytes crate fork)" documentation = "https://docs.rs/ntex-bytes" @@ -27,4 +27,4 @@ simdutf8 = { version = "0.1.4", optional = true } [dev-dependencies] serde_test = "1.0" serde_json = "1.0" -ntex = { version = "1.0.0", features = ["tokio"] } +ntex = { version = "1.0", features = ["tokio"] } diff --git a/ntex-bytes/src/bytes.rs b/ntex-bytes/src/bytes.rs index d869fd68..f04d634c 100644 --- a/ntex-bytes/src/bytes.rs +++ b/ntex-bytes/src/bytes.rs @@ -24,12 +24,12 @@ use crate::{buf::IntoIter, buf::UninitSlice, debug, Buf, BufMut}; /// let mut mem = Bytes::from(&b"Hello world"[..]); /// let a = mem.slice(0..5); /// -/// assert_eq!(&a[..], b"Hello"); +/// assert_eq!(a, b"Hello"); /// /// let b = mem.split_to(6); /// -/// assert_eq!(&mem[..], b"world"); -/// assert_eq!(&b[..], b"Hello "); +/// assert_eq!(mem, b"world"); +/// assert_eq!(b, b"Hello "); /// ``` /// /// # Memory layout @@ -135,7 +135,7 @@ pub struct Bytes { /// buf.put_u8(b'e'); /// buf.put("llo"); /// -/// assert_eq!(&buf[..], b"hello"); +/// assert_eq!(buf, b"hello"); /// /// // Freeze the buffer so that it can be shared /// let a = buf.freeze(); @@ -143,8 +143,8 @@ pub struct Bytes { /// // This does not allocate, instead `b` points to the same memory. /// let b = a.clone(); /// -/// assert_eq!(&a[..], b"hello"); -/// assert_eq!(&b[..], b"hello"); +/// assert_eq!(a, b"hello"); +/// assert_eq!(b, b"hello"); /// ``` pub struct BytesMut { inner: Inner, @@ -189,8 +189,8 @@ pub struct BytesMut { /// // This does not allocate, instead `b` points to the same memory. /// let b = a.clone(); /// -/// assert_eq!(&a[..], b"hello"); -/// assert_eq!(&b[..], b"hello"); +/// assert_eq!(a, b"hello"); +/// assert_eq!(b, b"hello"); /// ``` pub struct BytesVec { inner: InnerVec, @@ -536,7 +536,7 @@ impl Bytes { /// ``` /// use ntex_bytes::Bytes; /// - /// let a = Bytes::from(&b"hello world"[..]); + /// let a = Bytes::from(b"hello world"); /// let b = a.slice(2..5); /// /// assert_eq!(&b[..], b"llo"); @@ -601,7 +601,7 @@ impl Bytes { /// let as_slice = bytes.as_ref(); /// let subset = &as_slice[2..6]; /// let subslice = bytes.slice_ref(&subset); - /// assert_eq!(&subslice[..], b"2345"); + /// assert_eq!(subslice, b"2345"); /// ``` /// /// # Panics @@ -639,8 +639,8 @@ impl Bytes { /// let mut a = Bytes::from(&b"hello world"[..]); /// let b = a.split_off(5); /// - /// assert_eq!(&a[..], b"hello"); - /// assert_eq!(&b[..], b" world"); + /// assert_eq!(a, b"hello"); + /// assert_eq!(b, b" world"); /// ``` /// /// # Panics @@ -678,8 +678,8 @@ impl Bytes { /// let mut a = Bytes::from(&b"hello world"[..]); /// let b = a.split_to(5); /// - /// assert_eq!(&a[..], b" world"); - /// assert_eq!(&b[..], b"hello"); + /// assert_eq!(a, b" world"); + /// assert_eq!(b, b"hello"); /// ``` /// /// # Panics @@ -957,6 +957,12 @@ impl From<&'static str> for Bytes { } } +impl<'a, const N: usize> From<&'a [u8; N]> for Bytes { + fn from(src: &'a [u8; N]) -> Bytes { + Bytes::copy_from_slice(src) + } +} + impl FromIterator for Bytes { fn from_iter>(into_iter: T) -> Self { BytesMut::from_iter(into_iter).freeze() @@ -1218,17 +1224,17 @@ impl BytesMut { /// let b2 = b1.clone(); /// /// let th = thread::spawn(move || { - /// assert_eq!(&b1[..], b"hello world"); + /// assert_eq!(b1, b"hello world"); /// }); /// - /// assert_eq!(&b2[..], b"hello world"); + /// assert_eq!(b2, b"hello world"); /// th.join().unwrap(); /// ``` #[inline] pub fn freeze(self) -> Bytes { if self.inner.len() <= INLINE_CAP { Bytes { - inner: self.inner.to_inline(), + inner: Inner::from_slice_inline(self.inner.as_ref()), } } else { Bytes { inner: self.inner } @@ -1733,9 +1739,7 @@ impl From for BytesMut { impl<'a> From<&'a [u8]> for BytesMut { fn from(src: &'a [u8]) -> BytesMut { - let len = src.len(); - - if len == 0 { + if src.is_empty() { BytesMut::new() } else { BytesMut::copy_from_slice_in(src, PoolId::DEFAULT.pool_ref()) @@ -1743,6 +1747,18 @@ impl<'a> From<&'a [u8]> for BytesMut { } } +impl From<[u8; N]> for BytesMut { + fn from(src: [u8; N]) -> BytesMut { + BytesMut::copy_from_slice_in(src, PoolId::DEFAULT.pool_ref()) + } +} + +impl<'a, const N: usize> From<&'a [u8; N]> for BytesMut { + fn from(src: &'a [u8; N]) -> BytesMut { + BytesMut::copy_from_slice_in(src, PoolId::DEFAULT.pool_ref()) + } +} + impl<'a> From<&'a str> for BytesMut { #[inline] fn from(src: &'a str) -> BytesMut { @@ -2052,10 +2068,10 @@ impl BytesVec { /// let b2 = b1.clone(); /// /// let th = thread::spawn(move || { - /// assert_eq!(&b1[..], b"hello world"); + /// assert_eq!(b1, b"hello world"); /// }); /// - /// assert_eq!(&b2[..], b"hello world"); + /// assert_eq!(b2, b"hello world"); /// th.join().unwrap(); /// ``` #[inline] @@ -3149,22 +3165,6 @@ impl Inner { (self as *const Inner as *const u8).offset(INLINE_DATA_OFFSET) } - #[inline] - fn to_inline(&self) -> Inner { - unsafe { - let mut inner = Inner { - arc: NonNull::new_unchecked(KIND_INLINE as *mut Shared), - ptr: ptr::null_mut(), - cap: 0, - len: 0, - }; - let len = self.len(); - inner.as_raw()[..len].copy_from_slice(self.as_ref()); - inner.set_inline_len(len); - inner - } - } - #[inline] fn inline_len(&self) -> usize { // This is undefind behavior due to a data race, but experimental @@ -3708,12 +3708,30 @@ impl PartialEq<[u8]> for BytesMut { } } +impl PartialEq<[u8; N]> for BytesMut { + fn eq(&self, other: &[u8; N]) -> bool { + &**self == other + } +} + impl PartialEq for [u8] { fn eq(&self, other: &BytesMut) -> bool { *other == *self } } +impl PartialEq for [u8; N] { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + +impl<'a, const N: usize> PartialEq for &'a [u8; N] { + fn eq(&self, other: &BytesMut) -> bool { + *other == *self + } +} + impl PartialEq for BytesMut { fn eq(&self, other: &str) -> bool { &**self == other.as_bytes() @@ -3777,24 +3795,54 @@ impl PartialEq<[u8]> for Bytes { } } +impl PartialEq<[u8; N]> for Bytes { + fn eq(&self, other: &[u8; N]) -> bool { + self.inner.as_ref() == other.as_ref() + } +} + impl PartialOrd<[u8]> for Bytes { fn partial_cmp(&self, other: &[u8]) -> Option { self.inner.as_ref().partial_cmp(other) } } +impl PartialOrd<[u8; N]> for Bytes { + fn partial_cmp(&self, other: &[u8; N]) -> Option { + self.inner.as_ref().partial_cmp(other.as_ref()) + } +} + impl PartialEq for [u8] { fn eq(&self, other: &Bytes) -> bool { *other == *self } } +impl PartialEq for [u8; N] { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + +impl<'a, const N: usize> PartialEq for &'a [u8; N] { + fn eq(&self, other: &Bytes) -> bool { + *other == *self + } +} + impl PartialOrd for [u8] { fn partial_cmp(&self, other: &Bytes) -> Option { other.partial_cmp(self) } } +impl PartialOrd for [u8; N] { + fn partial_cmp(&self, other: &Bytes) -> Option { + other.partial_cmp(self) + } +} + impl PartialEq for Bytes { fn eq(&self, other: &str) -> bool { self.inner.as_ref() == other.as_bytes() @@ -3957,12 +4005,30 @@ impl PartialEq<[u8]> for BytesVec { } } +impl PartialEq<[u8; N]> for BytesVec { + fn eq(&self, other: &[u8; N]) -> bool { + &**self == other + } +} + impl PartialEq for [u8] { fn eq(&self, other: &BytesVec) -> bool { *other == *self } } +impl PartialEq for [u8; N] { + fn eq(&self, other: &BytesVec) -> bool { + *other == *self + } +} + +impl<'a, const N: usize> PartialEq for &'a [u8; N] { + fn eq(&self, other: &BytesVec) -> bool { + *other == *self + } +} + impl PartialEq for BytesVec { fn eq(&self, other: &str) -> bool { &**self == other.as_bytes() diff --git a/ntex-bytes/tests/test_buf.rs b/ntex-bytes/tests/test_buf.rs index a5787d2e..fd02b587 100644 --- a/ntex-bytes/tests/test_buf.rs +++ b/ntex-bytes/tests/test_buf.rs @@ -1,6 +1,6 @@ #![deny(warnings, rust_2018_idioms)] -use ntex_bytes::Buf; +use ntex_bytes::{Buf, Bytes, BytesMut}; #[test] fn test_fresh_cursor_vec() { @@ -20,6 +20,43 @@ fn test_fresh_cursor_vec() { assert_eq!(buf.chunk(), b""); } +#[test] +fn test_bytes() { + let mut buf = Bytes::from(b"hello"); + + assert_eq!(bytes::buf::Buf::remaining(&buf), 5); + assert_eq!(bytes::buf::Buf::chunk(&buf), b"hello"); + + bytes::buf::Buf::advance(&mut buf, 2); + + assert_eq!(bytes::buf::Buf::remaining(&buf), 3); + assert_eq!(bytes::buf::Buf::chunk(&buf), b"llo"); + + bytes::buf::Buf::advance(&mut buf, 3); + + assert_eq!(bytes::buf::Buf::remaining(&buf), 0); + assert_eq!(bytes::buf::Buf::chunk(&buf), b""); +} + +#[test] +fn test_bytes_mut() { + let mut buf = BytesMut::from(b"hello"); + + assert_eq!(bytes::buf::Buf::remaining(&buf), 5); + assert_eq!(bytes::buf::Buf::chunk(&buf), b"hello"); + + assert_eq!(bytes::buf::BufMut::remaining_mut(&mut buf), 27); + bytes::buf::Buf::advance(&mut buf, 2); + + assert_eq!(bytes::buf::Buf::remaining(&buf), 3); + assert_eq!(bytes::buf::Buf::chunk(&buf), b"llo"); + + bytes::buf::Buf::advance(&mut buf, 3); + + assert_eq!(bytes::buf::Buf::remaining(&buf), 0); + assert_eq!(bytes::buf::Buf::chunk(&buf), b""); +} + #[test] fn test_get_u8() { let mut buf = &b"\x21zomg"[..]; diff --git a/ntex-bytes/tests/test_bytes.rs b/ntex-bytes/tests/test_bytes.rs index c3294be3..2f50513d 100644 --- a/ntex-bytes/tests/test_bytes.rs +++ b/ntex-bytes/tests/test_bytes.rs @@ -207,9 +207,15 @@ fn index() { fn slice() { let a = Bytes::from(&b"hello world"[..]); + let b = a.slice(..); + assert_eq!(b, b"hello world"); + let b = a.slice(3..5); assert_eq!(b, b"lo"[..]); + let b = a.slice(3..=5); + assert_eq!(b, b"lo "[..]); + let b = a.slice(0..0); assert_eq!(b, b""[..]); @@ -460,29 +466,56 @@ fn split_off_to_at_gt_len() { clippy::needless_borrow )] fn fns_defined_for_bytes() { - let mut bytes = Bytes::from(&b"hello world"[..]); + let bytes = Bytes::from(&b"hello world"[..]); let _ = bytes.as_ptr(); assert_eq!(Borrow::<[u8]>::borrow(&bytes), b"hello world"); + let bytes = Bytes::from(b"hello world"); + assert_eq!(bytes, "hello world"); + assert_eq!(bytes, b"hello world"); + assert!(bytes > "g"); + assert!(bytes > b"g"); + assert!(bytes > [b'g']); + assert!(bytes > &[b'g'][..]); assert!(bytes > "g".to_string()); assert!(bytes > "g".as_bytes().to_vec()); assert!(bytes > Bytes::from("g")); assert!("g" > bytes); assert!("g".to_string() > bytes); assert!("g".as_bytes().to_vec() > bytes); + assert!([b'g'] > bytes); assert!(Bytes::from(&"g"[..]) < bytes); assert_eq!(bytes, "hello world"); assert_eq!(bytes, "hello world".as_bytes().to_vec()); assert_eq!(bytes, "hello world".to_string()); + assert_eq!(bytes, b"hello world"); assert_eq!(bytes, &"hello world"[..]); assert_eq!(bytes, BytesVec::copy_from_slice(b"hello world")); assert_eq!(bytes, BytesMut::copy_from_slice(b"hello world")); + assert_eq!(&bytes[..], b"hello world"); + assert_eq!(bytes.as_ref(), b"hello world"); assert_eq!("hello world", bytes); assert_eq!("hello world".as_bytes().to_vec(), bytes); assert_eq!("hello world".to_string(), bytes); + assert_eq!(b"hello world", bytes); assert_eq!(&"hello world"[..], bytes); + assert_eq!( + bytes, + [b'h', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd'] + ); + assert_eq!( + [b'h', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd'], + bytes, + ); + + let mut bytes = BytesMut::with_capacity(64); + bytes.put(LONG); + let bytes = bytes.freeze(); + assert_eq!(bytes.as_ref(), LONG); + + let mut bytes = Bytes::from(&b"hello world"[..]); // Iterator let v: Vec = (&bytes).iter().cloned().collect(); @@ -521,16 +554,35 @@ fn fns_defined_for_bytes_mut() { assert_eq!(Borrow::<[u8]>::borrow(&bytes), b"hello world"); assert_eq!(BorrowMut::<[u8]>::borrow_mut(&mut bytes), b"hello world"); + let mut bytes = BytesMut::from(b"hello world"); + assert_eq!(Borrow::<[u8]>::borrow(&bytes), b"hello world"); + assert_eq!(BorrowMut::<[u8]>::borrow_mut(&mut bytes), b"hello world"); + + let bytes = BytesMut::from([ + b'h', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd', + ]); + assert_eq!(Borrow::<[u8]>::borrow(&bytes), b"hello world"); + assert_eq!(bytes, "hello world"); assert_eq!(bytes, "hello world".as_bytes().to_vec()); assert_eq!(bytes, "hello world".to_string()); + assert_eq!(bytes, b"hello world"); assert_eq!(bytes, &"hello world"[..]); assert_eq!(bytes, Bytes::copy_from_slice(b"hello world")); assert_eq!(bytes, BytesVec::copy_from_slice(b"hello world")); + assert_eq!( + bytes, + [b'h', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd'] + ); assert_eq!("hello world", bytes); assert_eq!("hello world".as_bytes().to_vec(), bytes); assert_eq!("hello world".to_string(), bytes); + assert_eq!(b"hello world", bytes); assert_eq!(&"hello world"[..], bytes); + assert_eq!( + [b'h', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd'], + bytes + ); // Iterator let v: Vec = (&bytes).iter().cloned().collect(); @@ -584,16 +636,30 @@ fn fns_defined_for_bytes_vec() { assert_eq!(Borrow::<[u8]>::borrow(&bytes), b"hello world"); assert_eq!(BorrowMut::<[u8]>::borrow_mut(&mut bytes), b"hello world"); + let mut bytes = BytesVec::copy_from_slice(b"hello world"); + assert_eq!(Borrow::<[u8]>::borrow(&bytes), b"hello world"); + assert_eq!(BorrowMut::<[u8]>::borrow_mut(&mut bytes), b"hello world"); + assert_eq!(bytes, "hello world"); assert_eq!(bytes, "hello world".as_bytes().to_vec()); assert_eq!(bytes, "hello world".to_string()); + assert_eq!(bytes, b"hello world"); assert_eq!(bytes, &"hello world"[..]); assert_eq!(bytes, Bytes::copy_from_slice(b"hello world")); assert_eq!(bytes, BytesMut::copy_from_slice(b"hello world")); + assert_eq!(&bytes[..], b"hello world"); + assert_eq!( + bytes, + [b'h', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd'] + ); assert_eq!("hello world", bytes); assert_eq!("hello world".as_bytes().to_vec(), bytes); assert_eq!("hello world".to_string(), bytes); - assert_eq!("hello world", bytes); + assert_eq!(b"hello world", bytes); + assert_eq!( + [b'h', b'e', b'l', b'l', b'o', b' ', b'w', b'o', b'r', b'l', b'd'], + bytes + ); // Iterator let v: Vec = bytes.iter().cloned().collect(); @@ -815,7 +881,6 @@ fn advance_vec() { assert_eq!(a, b"d zomg wat wat"[..]); } -#[cfg(not(target_os = "macos"))] #[test] #[should_panic] fn advance_past_len() { @@ -823,7 +888,6 @@ fn advance_past_len() { a.advance(20); } -#[cfg(not(target_os = "macos"))] #[test] #[should_panic] fn advance_past_len_vec() {