Skip to main content

core/bstr/
traits.rs

1//! Trait implementations for `ByteStr`.
2
3use crate::bstr::ByteStr;
4use crate::cmp::Ordering;
5use crate::slice::SliceIndex;
6use crate::{hash, ops, range};
7
8#[unstable(feature = "bstr", issue = "134915")]
9#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
10const impl Ord for ByteStr {
11    #[inline]
12    fn cmp(&self, other: &ByteStr) -> Ordering {
13        Ord::cmp(&self.0, &other.0)
14    }
15}
16
17#[unstable(feature = "bstr", issue = "134915")]
18#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
19const impl PartialOrd for ByteStr {
20    #[inline]
21    fn partial_cmp(&self, other: &ByteStr) -> Option<Ordering> {
22        PartialOrd::partial_cmp(&self.0, &other.0)
23    }
24}
25
26#[unstable(feature = "bstr", issue = "134915")]
27#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
28const impl PartialEq<ByteStr> for ByteStr {
29    #[inline]
30    fn eq(&self, other: &ByteStr) -> bool {
31        self.0 == other.0
32    }
33}
34
35#[unstable(feature = "bstr", issue = "134915")]
36#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
37const impl Eq for ByteStr {}
38
39#[unstable(feature = "bstr", issue = "134915")]
40impl hash::Hash for ByteStr {
41    #[inline]
42    fn hash<H: hash::Hasher>(&self, state: &mut H) {
43        self.0.hash(state);
44    }
45}
46
47#[doc(hidden)]
48#[macro_export]
49#[unstable(feature = "bstr_internals", issue = "none")]
50macro_rules! impl_partial_eq {
51    ($lhs:ty, $rhs:ty) => {
52        impl PartialEq<$rhs> for $lhs {
53            #[inline]
54            fn eq(&self, other: &$rhs) -> bool {
55                let other: &[u8] = other.as_ref();
56                PartialEq::eq(self.as_bytes(), other)
57            }
58        }
59
60        impl PartialEq<$lhs> for $rhs {
61            #[inline]
62            fn eq(&self, other: &$lhs) -> bool {
63                let this: &[u8] = self.as_ref();
64                PartialEq::eq(this, other.as_bytes())
65            }
66        }
67    };
68}
69
70#[doc(hidden)]
71#[unstable(feature = "bstr_internals", issue = "none")]
72pub use impl_partial_eq;
73
74#[doc(hidden)]
75#[macro_export]
76#[unstable(feature = "bstr_internals", issue = "none")]
77macro_rules! impl_partial_eq_ord {
78    ($lhs:ty, $rhs:ty) => {
79        $crate::bstr::impl_partial_eq!($lhs, $rhs);
80
81        #[unstable(feature = "bstr", issue = "134915")]
82        impl PartialOrd<$rhs> for $lhs {
83            #[inline]
84            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
85                let other: &[u8] = other.as_ref();
86                PartialOrd::partial_cmp(self.as_bytes(), other)
87            }
88        }
89
90        #[unstable(feature = "bstr", issue = "134915")]
91        impl PartialOrd<$lhs> for $rhs {
92            #[inline]
93            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
94                let this: &[u8] = self.as_ref();
95                PartialOrd::partial_cmp(this, other.as_bytes())
96            }
97        }
98    };
99}
100
101#[doc(hidden)]
102#[unstable(feature = "bstr_internals", issue = "none")]
103pub use impl_partial_eq_ord;
104
105#[doc(hidden)]
106#[macro_export]
107#[unstable(feature = "bstr_internals", issue = "none")]
108macro_rules! impl_partial_eq_n {
109    ($lhs:ty, $rhs:ty) => {
110        #[unstable(feature = "bstr", issue = "134915")]
111        impl<const N: usize> PartialEq<$rhs> for $lhs {
112            #[inline]
113            fn eq(&self, other: &$rhs) -> bool {
114                let other: &[u8] = other.as_ref();
115                PartialEq::eq(self.as_bytes(), other)
116            }
117        }
118
119        #[unstable(feature = "bstr", issue = "134915")]
120        impl<const N: usize> PartialEq<$lhs> for $rhs {
121            #[inline]
122            fn eq(&self, other: &$lhs) -> bool {
123                let this: &[u8] = self.as_ref();
124                PartialEq::eq(this, other.as_bytes())
125            }
126        }
127    };
128}
129
130#[doc(hidden)]
131#[unstable(feature = "bstr_internals", issue = "none")]
132pub use impl_partial_eq_n;
133
134// PartialOrd with `[u8]` omitted to avoid inference failures
135impl_partial_eq!(ByteStr, [u8]);
136// PartialOrd with `&[u8]` omitted to avoid inference failures
137impl_partial_eq!(ByteStr, &[u8]);
138// PartialOrd with `str` omitted to avoid inference failures
139impl_partial_eq!(ByteStr, str);
140// PartialOrd with `&str` omitted to avoid inference failures
141impl_partial_eq!(ByteStr, &str);
142// PartialOrd with `[u8; N]` omitted to avoid inference failures
143impl_partial_eq_n!(ByteStr, [u8; N]);
144// PartialOrd with `[u8; N]` omitted to avoid inference failures
145impl_partial_eq_n!(ByteStr, &[u8; N]);
146
147#[unstable(feature = "bstr", issue = "134915")]
148impl<I> ops::Index<I> for ByteStr
149where
150    I: SliceIndex<ByteStr>,
151{
152    type Output = I::Output;
153
154    #[inline]
155    fn index(&self, index: I) -> &I::Output {
156        index.index(self)
157    }
158}
159
160#[unstable(feature = "bstr", issue = "134915")]
161impl<I> ops::IndexMut<I> for ByteStr
162where
163    I: SliceIndex<ByteStr>,
164{
165    #[inline]
166    fn index_mut(&mut self, index: I) -> &mut I::Output {
167        index.index_mut(self)
168    }
169}
170
171#[unstable(feature = "bstr", issue = "134915")]
172unsafe impl SliceIndex<ByteStr> for ops::RangeFull {
173    type Output = ByteStr;
174    #[inline]
175    fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
176        Some(slice)
177    }
178    #[inline]
179    fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
180        Some(slice)
181    }
182    #[inline]
183    unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
184        slice
185    }
186    #[inline]
187    unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
188        slice
189    }
190    #[inline]
191    fn index(self, slice: &ByteStr) -> &Self::Output {
192        slice
193    }
194    #[inline]
195    fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
196        slice
197    }
198}
199
200#[unstable(feature = "bstr", issue = "134915")]
201unsafe impl SliceIndex<ByteStr> for usize {
202    type Output = u8;
203    #[inline]
204    fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
205        self.get(slice.as_bytes())
206    }
207    #[inline]
208    fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
209        self.get_mut(slice.as_bytes_mut())
210    }
211    #[inline]
212    unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
213        // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
214        unsafe { self.get_unchecked(slice as *const [u8]) }
215    }
216    #[inline]
217    unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
218        // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
219        unsafe { self.get_unchecked_mut(slice as *mut [u8]) }
220    }
221    #[inline]
222    fn index(self, slice: &ByteStr) -> &Self::Output {
223        self.index(slice.as_bytes())
224    }
225    #[inline]
226    fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
227        self.index_mut(slice.as_bytes_mut())
228    }
229}
230
231macro_rules! impl_slice_index {
232    ($index:ty) => {
233        #[unstable(feature = "bstr", issue = "134915")]
234        unsafe impl SliceIndex<ByteStr> for $index {
235            type Output = ByteStr;
236            #[inline]
237            fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
238                self.get(slice.as_bytes()).map(ByteStr::from_bytes)
239            }
240            #[inline]
241            fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
242                self.get_mut(slice.as_bytes_mut()).map(ByteStr::from_bytes_mut)
243            }
244            #[inline]
245            unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
246                // SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
247                unsafe { self.get_unchecked(slice as *const [u8]) as *const ByteStr }
248            }
249            #[inline]
250            unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
251                // SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
252                unsafe { self.get_unchecked_mut(slice as *mut [u8]) as *mut ByteStr }
253            }
254            #[inline]
255            fn index(self, slice: &ByteStr) -> &Self::Output {
256                ByteStr::from_bytes(self.index(slice.as_bytes()))
257            }
258            #[inline]
259            fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
260                ByteStr::from_bytes_mut(self.index_mut(slice.as_bytes_mut()))
261            }
262        }
263    };
264}
265
266impl_slice_index!(ops::IndexRange);
267impl_slice_index!(ops::Range<usize>);
268impl_slice_index!(range::Range<usize>);
269impl_slice_index!(ops::RangeTo<usize>);
270impl_slice_index!(ops::RangeFrom<usize>);
271impl_slice_index!(range::RangeFrom<usize>);
272impl_slice_index!(ops::RangeInclusive<usize>);
273impl_slice_index!(range::RangeInclusive<usize>);
274impl_slice_index!(ops::RangeToInclusive<usize>);
275impl_slice_index!(range::RangeToInclusive<usize>);
276impl_slice_index!((ops::Bound<usize>, ops::Bound<usize>));