| //! Trait implementations for `ByteStr`. | |
| use crate::bstr::ByteStr; | |
| use crate::cmp::Ordering; | |
| use crate::slice::SliceIndex; | |
| use crate::{hash, ops, range}; | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl Ord for ByteStr { | |
| #[inline] | |
| fn cmp(&self, other: &ByteStr) -> Ordering { | |
| Ord::cmp(&self.0, &other.0) | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl PartialOrd for ByteStr { | |
| #[inline] | |
| fn partial_cmp(&self, other: &ByteStr) -> Option<Ordering> { | |
| PartialOrd::partial_cmp(&self.0, &other.0) | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl PartialEq<ByteStr> for ByteStr { | |
| #[inline] | |
| fn eq(&self, other: &ByteStr) -> bool { | |
| &self.0 == &other.0 | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl Eq for ByteStr {} | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl hash::Hash for ByteStr { | |
| #[inline] | |
| fn hash<H: hash::Hasher>(&self, state: &mut H) { | |
| self.0.hash(state); | |
| } | |
| } | |
| #[doc(hidden)] | |
| #[macro_export] | |
| #[unstable(feature = "bstr_internals", issue = "none")] | |
| macro_rules! impl_partial_eq { | |
| ($lhs:ty, $rhs:ty) => { | |
| impl PartialEq<$rhs> for $lhs { | |
| #[inline] | |
| fn eq(&self, other: &$rhs) -> bool { | |
| let other: &[u8] = other.as_ref(); | |
| PartialEq::eq(self.as_bytes(), other) | |
| } | |
| } | |
| impl PartialEq<$lhs> for $rhs { | |
| #[inline] | |
| fn eq(&self, other: &$lhs) -> bool { | |
| let this: &[u8] = self.as_ref(); | |
| PartialEq::eq(this, other.as_bytes()) | |
| } | |
| } | |
| }; | |
| } | |
| #[doc(hidden)] | |
| #[unstable(feature = "bstr_internals", issue = "none")] | |
| pub use impl_partial_eq; | |
| #[doc(hidden)] | |
| #[macro_export] | |
| #[unstable(feature = "bstr_internals", issue = "none")] | |
| macro_rules! impl_partial_eq_ord { | |
| ($lhs:ty, $rhs:ty) => { | |
| $crate::bstr::impl_partial_eq!($lhs, $rhs); | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl PartialOrd<$rhs> for $lhs { | |
| #[inline] | |
| fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> { | |
| let other: &[u8] = other.as_ref(); | |
| PartialOrd::partial_cmp(self.as_bytes(), other) | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl PartialOrd<$lhs> for $rhs { | |
| #[inline] | |
| fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> { | |
| let this: &[u8] = self.as_ref(); | |
| PartialOrd::partial_cmp(this, other.as_bytes()) | |
| } | |
| } | |
| }; | |
| } | |
| #[doc(hidden)] | |
| #[unstable(feature = "bstr_internals", issue = "none")] | |
| pub use impl_partial_eq_ord; | |
| #[doc(hidden)] | |
| #[macro_export] | |
| #[unstable(feature = "bstr_internals", issue = "none")] | |
| macro_rules! impl_partial_eq_n { | |
| ($lhs:ty, $rhs:ty) => { | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl<const N: usize> PartialEq<$rhs> for $lhs { | |
| #[inline] | |
| fn eq(&self, other: &$rhs) -> bool { | |
| let other: &[u8] = other.as_ref(); | |
| PartialEq::eq(self.as_bytes(), other) | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl<const N: usize> PartialEq<$lhs> for $rhs { | |
| #[inline] | |
| fn eq(&self, other: &$lhs) -> bool { | |
| let this: &[u8] = self.as_ref(); | |
| PartialEq::eq(this, other.as_bytes()) | |
| } | |
| } | |
| }; | |
| } | |
| #[doc(hidden)] | |
| #[unstable(feature = "bstr_internals", issue = "none")] | |
| pub use impl_partial_eq_n; | |
| // PartialOrd with `[u8]` omitted to avoid inference failures | |
| impl_partial_eq!(ByteStr, [u8]); | |
| // PartialOrd with `&[u8]` omitted to avoid inference failures | |
| impl_partial_eq!(ByteStr, &[u8]); | |
| // PartialOrd with `str` omitted to avoid inference failures | |
| impl_partial_eq!(ByteStr, str); | |
| // PartialOrd with `&str` omitted to avoid inference failures | |
| impl_partial_eq!(ByteStr, &str); | |
| // PartialOrd with `[u8; N]` omitted to avoid inference failures | |
| impl_partial_eq_n!(ByteStr, [u8; N]); | |
| // PartialOrd with `[u8; N]` omitted to avoid inference failures | |
| impl_partial_eq_n!(ByteStr, &[u8; N]); | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl<I> ops::Index<I> for ByteStr | |
| where | |
| I: SliceIndex<ByteStr>, | |
| { | |
| type Output = I::Output; | |
| #[inline] | |
| fn index(&self, index: I) -> &I::Output { | |
| index.index(self) | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| impl<I> ops::IndexMut<I> for ByteStr | |
| where | |
| I: SliceIndex<ByteStr>, | |
| { | |
| #[inline] | |
| fn index_mut(&mut self, index: I) -> &mut I::Output { | |
| index.index_mut(self) | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| unsafe impl SliceIndex<ByteStr> for ops::RangeFull { | |
| type Output = ByteStr; | |
| #[inline] | |
| fn get(self, slice: &ByteStr) -> Option<&Self::Output> { | |
| Some(slice) | |
| } | |
| #[inline] | |
| fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> { | |
| Some(slice) | |
| } | |
| #[inline] | |
| unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output { | |
| slice | |
| } | |
| #[inline] | |
| unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output { | |
| slice | |
| } | |
| #[inline] | |
| fn index(self, slice: &ByteStr) -> &Self::Output { | |
| slice | |
| } | |
| #[inline] | |
| fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output { | |
| slice | |
| } | |
| } | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| unsafe impl SliceIndex<ByteStr> for usize { | |
| type Output = u8; | |
| #[inline] | |
| fn get(self, slice: &ByteStr) -> Option<&Self::Output> { | |
| self.get(slice.as_bytes()) | |
| } | |
| #[inline] | |
| fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> { | |
| self.get_mut(slice.as_bytes_mut()) | |
| } | |
| #[inline] | |
| unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output { | |
| // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. | |
| unsafe { self.get_unchecked(slice as *const [u8]) } | |
| } | |
| #[inline] | |
| unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output { | |
| // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. | |
| unsafe { self.get_unchecked_mut(slice as *mut [u8]) } | |
| } | |
| #[inline] | |
| fn index(self, slice: &ByteStr) -> &Self::Output { | |
| self.index(slice.as_bytes()) | |
| } | |
| #[inline] | |
| fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output { | |
| self.index_mut(slice.as_bytes_mut()) | |
| } | |
| } | |
| macro_rules! impl_slice_index { | |
| ($index:ty) => { | |
| #[unstable(feature = "bstr", issue = "134915")] | |
| unsafe impl SliceIndex<ByteStr> for $index { | |
| type Output = ByteStr; | |
| #[inline] | |
| fn get(self, slice: &ByteStr) -> Option<&Self::Output> { | |
| self.get(slice.as_bytes()).map(ByteStr::from_bytes) | |
| } | |
| #[inline] | |
| fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> { | |
| self.get_mut(slice.as_bytes_mut()).map(ByteStr::from_bytes_mut) | |
| } | |
| #[inline] | |
| unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output { | |
| // SAFETY: the caller has to uphold the safety contract for `get_unchecked`. | |
| unsafe { self.get_unchecked(slice as *const [u8]) as *const ByteStr } | |
| } | |
| #[inline] | |
| unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output { | |
| // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`. | |
| unsafe { self.get_unchecked_mut(slice as *mut [u8]) as *mut ByteStr } | |
| } | |
| #[inline] | |
| fn index(self, slice: &ByteStr) -> &Self::Output { | |
| ByteStr::from_bytes(self.index(slice.as_bytes())) | |
| } | |
| #[inline] | |
| fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output { | |
| ByteStr::from_bytes_mut(self.index_mut(slice.as_bytes_mut())) | |
| } | |
| } | |
| }; | |
| } | |
| impl_slice_index!(ops::IndexRange); | |
| impl_slice_index!(ops::Range<usize>); | |
| impl_slice_index!(range::Range<usize>); | |
| impl_slice_index!(ops::RangeTo<usize>); | |
| impl_slice_index!(ops::RangeFrom<usize>); | |
| impl_slice_index!(range::RangeFrom<usize>); | |
| impl_slice_index!(ops::RangeInclusive<usize>); | |
| impl_slice_index!(range::RangeInclusive<usize>); | |
| impl_slice_index!(ops::RangeToInclusive<usize>); | |
| impl_slice_index!(range::RangeToInclusive<usize>); | |
| impl_slice_index!((ops::Bound<usize>, ops::Bound<usize>)); |