| macro_rules! impl_partial_eq { |
| ($lhs:ty, $rhs:ty) => { |
| impl<'a, 'b> PartialEq<$rhs> for $lhs { |
| #[inline] |
| fn eq(&self, other: &$rhs) -> bool { |
| let l = self.as_ref(); |
| let r: &Self = other.as_ref(); |
| PartialEq::eq(l, r) |
| } |
| } |
| |
| impl<'a, 'b> PartialEq<$lhs> for $rhs { |
| #[inline] |
| fn eq(&self, other: &$lhs) -> bool { |
| PartialEq::eq(other, self) |
| } |
| } |
| }; |
| } |
| |
| macro_rules! impl_partial_ord { |
| ($lhs:ty, $rhs:ty) => { |
| impl<'a, 'b> PartialOrd<$rhs> for $lhs { |
| #[inline] |
| fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> { |
| let l = self.as_ref(); |
| let r: &Self = other.as_ref(); |
| PartialOrd::partial_cmp(l, r) |
| } |
| } |
| |
| impl<'a, 'b> PartialOrd<$lhs> for $rhs { |
| #[inline] |
| fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> { |
| PartialOrd::partial_cmp(other, self) |
| } |
| } |
| }; |
| } |
| |
| mod bytes { |
| use crate::lib::std::{cmp::Ordering, fmt, ops}; |
| |
| use crate::stream::Bytes; |
| |
| impl fmt::Display for Bytes { |
| #[inline] |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| <Self as fmt::UpperHex>::fmt(self, f) |
| } |
| } |
| |
| impl fmt::Debug for Bytes { |
| #[inline] |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| <Self as fmt::UpperHex>::fmt(self, f) |
| } |
| } |
| |
| impl fmt::LowerHex for Bytes { |
| #[inline] |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| for byte in self.as_bytes() { |
| write!(f, "{:0>2x}", byte)?; |
| } |
| Ok(()) |
| } |
| } |
| |
| impl fmt::UpperHex for Bytes { |
| #[inline] |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| for (i, byte) in self.as_bytes().iter().enumerate() { |
| if 0 < i { |
| let absolute = (self.as_bytes().as_ptr() as usize) + i; |
| if f.alternate() && absolute != 0 && absolute % 4 == 0 { |
| write!(f, "_")?; |
| } |
| } |
| write!(f, "{:0>2X}", byte)?; |
| } |
| Ok(()) |
| } |
| } |
| |
| impl ops::Deref for Bytes { |
| type Target = [u8]; |
| |
| #[inline] |
| fn deref(&self) -> &[u8] { |
| self.as_bytes() |
| } |
| } |
| |
| impl ops::Index<usize> for Bytes { |
| type Output = u8; |
| |
| #[inline] |
| fn index(&self, idx: usize) -> &u8 { |
| &self.as_bytes()[idx] |
| } |
| } |
| |
| impl ops::Index<ops::RangeFull> for Bytes { |
| type Output = Bytes; |
| |
| #[inline] |
| fn index(&self, _: ops::RangeFull) -> &Bytes { |
| self |
| } |
| } |
| |
| impl ops::Index<ops::Range<usize>> for Bytes { |
| type Output = Bytes; |
| |
| #[inline] |
| fn index(&self, r: ops::Range<usize>) -> &Bytes { |
| Bytes::new(&self.as_bytes()[r.start..r.end]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeInclusive<usize>> for Bytes { |
| type Output = Bytes; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeInclusive<usize>) -> &Bytes { |
| Bytes::new(&self.as_bytes()[*r.start()..=*r.end()]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeFrom<usize>> for Bytes { |
| type Output = Bytes; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeFrom<usize>) -> &Bytes { |
| Bytes::new(&self.as_bytes()[r.start..]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeTo<usize>> for Bytes { |
| type Output = Bytes; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeTo<usize>) -> &Bytes { |
| Bytes::new(&self.as_bytes()[..r.end]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeToInclusive<usize>> for Bytes { |
| type Output = Bytes; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeToInclusive<usize>) -> &Bytes { |
| Bytes::new(&self.as_bytes()[..=r.end]) |
| } |
| } |
| |
| impl AsRef<[u8]> for Bytes { |
| #[inline] |
| fn as_ref(&self) -> &[u8] { |
| self.as_bytes() |
| } |
| } |
| |
| impl AsRef<Bytes> for [u8] { |
| #[inline] |
| fn as_ref(&self) -> &Bytes { |
| Bytes::new(self) |
| } |
| } |
| |
| impl AsRef<Bytes> for str { |
| #[inline] |
| fn as_ref(&self) -> &Bytes { |
| Bytes::new(self) |
| } |
| } |
| |
| #[cfg(feature = "alloc")] |
| impl crate::lib::std::borrow::ToOwned for Bytes { |
| type Owned = crate::lib::std::vec::Vec<u8>; |
| |
| #[inline] |
| fn to_owned(&self) -> Self::Owned { |
| crate::lib::std::vec::Vec::from(self.as_bytes()) |
| } |
| } |
| |
| #[cfg(feature = "alloc")] |
| impl crate::lib::std::borrow::Borrow<Bytes> for crate::lib::std::vec::Vec<u8> { |
| #[inline] |
| fn borrow(&self) -> &Bytes { |
| Bytes::from_bytes(self.as_slice()) |
| } |
| } |
| |
| impl<'a> Default for &'a Bytes { |
| fn default() -> &'a Bytes { |
| Bytes::new(b"") |
| } |
| } |
| |
| impl<'a> From<&'a [u8]> for &'a Bytes { |
| #[inline] |
| fn from(s: &'a [u8]) -> &'a Bytes { |
| Bytes::new(s) |
| } |
| } |
| |
| impl<'a> From<&'a Bytes> for &'a [u8] { |
| #[inline] |
| fn from(s: &'a Bytes) -> &'a [u8] { |
| Bytes::as_bytes(s) |
| } |
| } |
| |
| impl<'a> From<&'a str> for &'a Bytes { |
| #[inline] |
| fn from(s: &'a str) -> &'a Bytes { |
| Bytes::new(s.as_bytes()) |
| } |
| } |
| |
| impl Eq for Bytes {} |
| |
| impl PartialEq<Bytes> for Bytes { |
| #[inline] |
| fn eq(&self, other: &Bytes) -> bool { |
| self.as_bytes() == other.as_bytes() |
| } |
| } |
| |
| impl_partial_eq!(Bytes, [u8]); |
| impl_partial_eq!(Bytes, &'a [u8]); |
| impl_partial_eq!(Bytes, str); |
| impl_partial_eq!(Bytes, &'a str); |
| |
| impl PartialOrd for Bytes { |
| #[inline] |
| fn partial_cmp(&self, other: &Bytes) -> Option<Ordering> { |
| Some(self.cmp(other)) |
| } |
| } |
| |
| impl Ord for Bytes { |
| #[inline] |
| fn cmp(&self, other: &Bytes) -> Ordering { |
| Ord::cmp(self.as_bytes(), other.as_bytes()) |
| } |
| } |
| |
| impl_partial_ord!(Bytes, [u8]); |
| impl_partial_ord!(Bytes, &'a [u8]); |
| impl_partial_ord!(Bytes, str); |
| impl_partial_ord!(Bytes, &'a str); |
| |
| #[cfg(all(test, feature = "std"))] |
| mod display { |
| use crate::stream::Bytes; |
| |
| #[test] |
| fn clean() { |
| assert_eq!(&format!("{}", Bytes::new(b"abc")), "616263"); |
| assert_eq!(&format!("{}", Bytes::new(b"\xf0\x28\x8c\xbc")), "F0288CBC"); |
| } |
| } |
| |
| #[cfg(all(test, feature = "std"))] |
| mod debug { |
| use crate::stream::Bytes; |
| |
| #[test] |
| fn test_debug() { |
| assert_eq!( |
| "000000206674797069736F6D0000020069736F6D69736F32617663316D70", |
| format!( |
| "{:?}", |
| Bytes::new(b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp") |
| ), |
| ); |
| } |
| |
| #[test] |
| fn test_pretty_debug() { |
| // Output can change from run-to-run |
| format!( |
| "{:#?}", |
| Bytes::new(b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp") |
| ); |
| } |
| |
| #[test] |
| fn test_sliced() { |
| // Output can change from run-to-run |
| let total = Bytes::new(b"12345678901234567890"); |
| format!("{:#?}", total); |
| format!("{:#?}", &total[1..]); |
| format!("{:#?}", &total[10..]); |
| } |
| } |
| } |
| |
| mod bstr { |
| use crate::lib::std::{cmp::Ordering, fmt, ops}; |
| |
| use crate::stream::BStr; |
| |
| #[cfg(feature = "alloc")] |
| impl fmt::Display for BStr { |
| #[inline] |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| crate::lib::std::string::String::from_utf8_lossy(self.as_bytes()).fmt(f) |
| } |
| } |
| |
| impl fmt::Debug for BStr { |
| #[inline] |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| if !f.alternate() { |
| write!(f, "\"")?; |
| } |
| for byte in self.as_bytes() { |
| let c = *byte as char; |
| write!(f, "{}", c.escape_debug())?; |
| } |
| if !f.alternate() { |
| write!(f, "\"")?; |
| } |
| Ok(()) |
| } |
| } |
| |
| impl ops::Deref for BStr { |
| type Target = [u8]; |
| |
| #[inline] |
| fn deref(&self) -> &[u8] { |
| self.as_bytes() |
| } |
| } |
| |
| impl ops::Index<usize> for BStr { |
| type Output = u8; |
| |
| #[inline] |
| fn index(&self, idx: usize) -> &u8 { |
| &self.as_bytes()[idx] |
| } |
| } |
| |
| impl ops::Index<ops::RangeFull> for BStr { |
| type Output = BStr; |
| |
| #[inline] |
| fn index(&self, _: ops::RangeFull) -> &BStr { |
| self |
| } |
| } |
| |
| impl ops::Index<ops::Range<usize>> for BStr { |
| type Output = BStr; |
| |
| #[inline] |
| fn index(&self, r: ops::Range<usize>) -> &BStr { |
| BStr::new(&self.as_bytes()[r.start..r.end]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeInclusive<usize>> for BStr { |
| type Output = BStr; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeInclusive<usize>) -> &BStr { |
| BStr::new(&self.as_bytes()[*r.start()..=*r.end()]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeFrom<usize>> for BStr { |
| type Output = BStr; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeFrom<usize>) -> &BStr { |
| BStr::new(&self.as_bytes()[r.start..]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeTo<usize>> for BStr { |
| type Output = BStr; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeTo<usize>) -> &BStr { |
| BStr::new(&self.as_bytes()[..r.end]) |
| } |
| } |
| |
| impl ops::Index<ops::RangeToInclusive<usize>> for BStr { |
| type Output = BStr; |
| |
| #[inline] |
| fn index(&self, r: ops::RangeToInclusive<usize>) -> &BStr { |
| BStr::new(&self.as_bytes()[..=r.end]) |
| } |
| } |
| |
| impl AsRef<[u8]> for BStr { |
| #[inline] |
| fn as_ref(&self) -> &[u8] { |
| self.as_bytes() |
| } |
| } |
| |
| impl AsRef<BStr> for [u8] { |
| #[inline] |
| fn as_ref(&self) -> &BStr { |
| BStr::new(self) |
| } |
| } |
| |
| impl AsRef<BStr> for str { |
| #[inline] |
| fn as_ref(&self) -> &BStr { |
| BStr::new(self) |
| } |
| } |
| |
| #[cfg(feature = "alloc")] |
| impl crate::lib::std::borrow::ToOwned for BStr { |
| type Owned = crate::lib::std::vec::Vec<u8>; |
| |
| #[inline] |
| fn to_owned(&self) -> Self::Owned { |
| crate::lib::std::vec::Vec::from(self.as_bytes()) |
| } |
| } |
| |
| #[cfg(feature = "alloc")] |
| impl crate::lib::std::borrow::Borrow<BStr> for crate::lib::std::vec::Vec<u8> { |
| #[inline] |
| fn borrow(&self) -> &BStr { |
| BStr::from_bytes(self.as_slice()) |
| } |
| } |
| |
| impl<'a> Default for &'a BStr { |
| fn default() -> &'a BStr { |
| BStr::new(b"") |
| } |
| } |
| |
| impl<'a> From<&'a [u8]> for &'a BStr { |
| #[inline] |
| fn from(s: &'a [u8]) -> &'a BStr { |
| BStr::new(s) |
| } |
| } |
| |
| impl<'a> From<&'a BStr> for &'a [u8] { |
| #[inline] |
| fn from(s: &'a BStr) -> &'a [u8] { |
| BStr::as_bytes(s) |
| } |
| } |
| |
| impl<'a> From<&'a str> for &'a BStr { |
| #[inline] |
| fn from(s: &'a str) -> &'a BStr { |
| BStr::new(s.as_bytes()) |
| } |
| } |
| |
| impl Eq for BStr {} |
| |
| impl PartialEq<BStr> for BStr { |
| #[inline] |
| fn eq(&self, other: &BStr) -> bool { |
| self.as_bytes() == other.as_bytes() |
| } |
| } |
| |
| impl_partial_eq!(BStr, [u8]); |
| impl_partial_eq!(BStr, &'a [u8]); |
| impl_partial_eq!(BStr, str); |
| impl_partial_eq!(BStr, &'a str); |
| |
| impl PartialOrd for BStr { |
| #[inline] |
| fn partial_cmp(&self, other: &BStr) -> Option<Ordering> { |
| Some(self.cmp(other)) |
| } |
| } |
| |
| impl Ord for BStr { |
| #[inline] |
| fn cmp(&self, other: &BStr) -> Ordering { |
| Ord::cmp(self.as_bytes(), other.as_bytes()) |
| } |
| } |
| |
| impl_partial_ord!(BStr, [u8]); |
| impl_partial_ord!(BStr, &'a [u8]); |
| impl_partial_ord!(BStr, str); |
| impl_partial_ord!(BStr, &'a str); |
| |
| #[cfg(all(test, feature = "std"))] |
| mod display { |
| use crate::stream::BStr; |
| |
| #[test] |
| fn clean() { |
| assert_eq!(&format!("{}", BStr::new(b"abc")), "abc"); |
| assert_eq!(&format!("{}", BStr::new(b"\xf0\x28\x8c\xbc")), "�(��"); |
| } |
| } |
| |
| #[cfg(all(test, feature = "std"))] |
| mod debug { |
| use crate::stream::BStr; |
| |
| #[test] |
| fn test_debug() { |
| assert_eq!(&format!("{:?}", BStr::new(b"abc")), "\"abc\""); |
| |
| assert_eq!( |
| "\"\\0\\0\\0 ftypisom\\0\\0\\u{2}\\0isomiso2avc1mp\"", |
| format!( |
| "{:?}", |
| BStr::new(b"\0\0\0 ftypisom\0\0\x02\0isomiso2avc1mp") |
| ), |
| ); |
| } |
| |
| #[test] |
| fn test_pretty_debug() { |
| assert_eq!(&format!("{:#?}", BStr::new(b"abc")), "abc"); |
| } |
| } |
| } |