Skip to main content

alloc/
bstr.rs

1//! The `ByteStr` and `ByteString` types and trait implementations.
2
3// This could be more fine-grained.
4#![cfg(not(no_global_oom_handling))]
5
6use core::borrow::{Borrow, BorrowMut};
7#[unstable(feature = "bstr", issue = "134915")]
8pub use core::bstr::ByteStr;
9use core::bstr::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord};
10use core::cmp::Ordering;
11use core::ops::{
12    Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive,
13    RangeTo, RangeToInclusive,
14};
15use core::str::{FromStr, Utf8Error};
16use core::{fmt, hash};
17
18use crate::borrow::{Cow, ToOwned};
19use crate::boxed::Box;
20#[cfg(not(no_rc))]
21use crate::rc::Rc;
22use crate::string::String;
23#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
24use crate::sync::Arc;
25use crate::vec::Vec;
26
27/// A wrapper for `Vec<u8>` representing a human-readable string that's conventionally, but not
28/// always, UTF-8.
29///
30/// Unlike `String`, this type permits non-UTF-8 contents, making it suitable for user input,
31/// non-native filenames (as `Path` only supports native filenames), and other applications that
32/// need to round-trip whatever data the user provides.
33///
34/// A `ByteString` owns its contents and can grow and shrink, like a `Vec` or `String`. For a
35/// borrowed byte string, see [`ByteStr`](../../std/bstr/struct.ByteStr.html).
36///
37/// `ByteString` implements `Deref` to `&Vec<u8>`, so all methods available on `&Vec<u8>` are
38/// available on `ByteString`. Similarly, `ByteString` implements `DerefMut` to `&mut Vec<u8>`,
39/// so you can modify a `ByteString` using any method available on `&mut Vec<u8>`.
40///
41/// The `Debug` and `Display` implementations for `ByteString` are the same as those for `ByteStr`,
42/// showing invalid UTF-8 as hex escapes or the Unicode replacement character, respectively.
43#[unstable(feature = "bstr", issue = "134915")]
44#[repr(transparent)]
45#[derive(#[automatically_derived]
#[unstable(feature = "bstr", issue = "134915")]
impl ::core::clone::Clone for ByteString {
    #[inline]
    fn clone(&self) -> ByteString {
        ByteString(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
#[unstable(feature = "bstr", issue = "134915")]
impl ::core::default::Default for ByteString {
    #[inline]
    fn default() -> ByteString {
        ByteString(::core::default::Default::default())
    }
}Default)]
46#[doc(alias = "BString")]
47pub struct ByteString(pub Vec<u8>);
48
49impl ByteString {
50    #[inline]
51    pub(crate) fn as_bytes(&self) -> &[u8] {
52        &self.0
53    }
54
55    #[inline]
56    pub(crate) fn as_bytestr(&self) -> &ByteStr {
57        ByteStr::new(&self.0)
58    }
59
60    #[inline]
61    pub(crate) fn as_mut_bytestr(&mut self) -> &mut ByteStr {
62        ByteStr::from_bytes_mut(&mut self.0)
63    }
64    /// Try to get a `String` representation of the `&ByteString`, if it is
65    /// valid UTF-8.
66    ///
67    /// This method is named `to_string()` because we want `ByteString` to
68    /// implement `Display`, but the `ToString` trait has a blanket
69    /// implementation for types that implement `Display`, and the trait version
70    /// will use the Unicode replacement character rather than returning a
71    /// `Result` and allowing for the possibility of the content not being UTF-8.
72    #[unstable(feature = "bstr_to_string", issue = "134915")]
73    #[rustc_allow_incoherent_impl]
74    pub fn to_string(&self) -> Result<String, Utf8Error> {
75        // Avoid allocating a copy of the contents for invalid UTF-8
76        if let Err(e) = str::from_utf8(&self.0) {
77            return Err(e);
78        }
79        // SAFETY: we just checked that the contents are valid UTF-8
80        Ok(unsafe { String::from_utf8_unchecked(self.0.clone()) })
81    }
82}
83
84#[unstable(feature = "bstr", issue = "134915")]
85impl Deref for ByteString {
86    type Target = Vec<u8>;
87
88    #[inline]
89    fn deref(&self) -> &Self::Target {
90        &self.0
91    }
92}
93
94#[unstable(feature = "bstr", issue = "134915")]
95impl DerefMut for ByteString {
96    #[inline]
97    fn deref_mut(&mut self) -> &mut Self::Target {
98        &mut self.0
99    }
100}
101
102#[unstable(feature = "deref_pure_trait", issue = "87121")]
103unsafe impl DerefPure for ByteString {}
104
105#[unstable(feature = "bstr", issue = "134915")]
106impl fmt::Debug for ByteString {
107    #[inline]
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        fmt::Debug::fmt(self.as_bytestr(), f)
110    }
111}
112
113#[unstable(feature = "bstr_to_string", issue = "134915")]
114impl fmt::Display for ByteString {
115    #[inline]
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        fmt::Display::fmt(self.as_bytestr(), f)
118    }
119}
120
121#[unstable(feature = "bstr", issue = "134915")]
122impl AsRef<[u8]> for ByteString {
123    #[inline]
124    fn as_ref(&self) -> &[u8] {
125        &self.0
126    }
127}
128
129#[unstable(feature = "bstr", issue = "134915")]
130impl AsRef<ByteStr> for ByteString {
131    #[inline]
132    fn as_ref(&self) -> &ByteStr {
133        self.as_bytestr()
134    }
135}
136
137#[unstable(feature = "bstr", issue = "134915")]
138impl AsMut<[u8]> for ByteString {
139    #[inline]
140    fn as_mut(&mut self) -> &mut [u8] {
141        &mut self.0
142    }
143}
144
145#[unstable(feature = "bstr", issue = "134915")]
146impl AsMut<ByteStr> for ByteString {
147    #[inline]
148    fn as_mut(&mut self) -> &mut ByteStr {
149        self.as_mut_bytestr()
150    }
151}
152
153#[unstable(feature = "bstr", issue = "134915")]
154impl Borrow<[u8]> for ByteString {
155    #[inline]
156    fn borrow(&self) -> &[u8] {
157        &self.0
158    }
159}
160
161#[unstable(feature = "bstr", issue = "134915")]
162impl Borrow<ByteStr> for ByteString {
163    #[inline]
164    fn borrow(&self) -> &ByteStr {
165        self.as_bytestr()
166    }
167}
168
169// `impl Borrow<ByteStr> for Vec<u8>` omitted to avoid inference failures
170// `impl Borrow<ByteStr> for String` omitted to avoid inference failures
171
172#[unstable(feature = "bstr", issue = "134915")]
173impl BorrowMut<[u8]> for ByteString {
174    #[inline]
175    fn borrow_mut(&mut self) -> &mut [u8] {
176        &mut self.0
177    }
178}
179
180#[unstable(feature = "bstr", issue = "134915")]
181impl BorrowMut<ByteStr> for ByteString {
182    #[inline]
183    fn borrow_mut(&mut self) -> &mut ByteStr {
184        self.as_mut_bytestr()
185    }
186}
187
188// `impl BorrowMut<ByteStr> for Vec<u8>` omitted to avoid inference failures
189
190// Omitted due to inference failures
191//
192// #[unstable(feature = "bstr", issue = "134915")]
193// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString {
194//     #[inline]
195//     fn from(s: &'a [u8; N]) -> Self {
196//         ByteString(s.as_slice().to_vec())
197//     }
198// }
199//
200// #[unstable(feature = "bstr", issue = "134915")]
201// impl<const N: usize> From<[u8; N]> for ByteString {
202//     #[inline]
203//     fn from(s: [u8; N]) -> Self {
204//         ByteString(s.as_slice().to_vec())
205//     }
206// }
207//
208// #[unstable(feature = "bstr", issue = "134915")]
209// impl<'a> From<&'a [u8]> for ByteString {
210//     #[inline]
211//     fn from(s: &'a [u8]) -> Self {
212//         ByteString(s.to_vec())
213//     }
214// }
215//
216// #[unstable(feature = "bstr", issue = "134915")]
217// impl From<Vec<u8>> for ByteString {
218//     #[inline]
219//     fn from(s: Vec<u8>) -> Self {
220//         ByteString(s)
221//     }
222// }
223
224#[unstable(feature = "bstr", issue = "134915")]
225impl From<ByteString> for Vec<u8> {
226    #[inline]
227    fn from(s: ByteString) -> Self {
228        s.0
229    }
230}
231
232// Omitted due to inference failures
233//
234// #[unstable(feature = "bstr", issue = "134915")]
235// impl<'a> From<&'a str> for ByteString {
236//     #[inline]
237//     fn from(s: &'a str) -> Self {
238//         ByteString(s.as_bytes().to_vec())
239//     }
240// }
241//
242// #[unstable(feature = "bstr", issue = "134915")]
243// impl From<String> for ByteString {
244//     #[inline]
245//     fn from(s: String) -> Self {
246//         ByteString(s.into_bytes())
247//     }
248// }
249
250#[unstable(feature = "bstr", issue = "134915")]
251impl<'a> From<&'a ByteStr> for ByteString {
252    #[inline]
253    fn from(s: &'a ByteStr) -> Self {
254        ByteString(s.0.to_vec())
255    }
256}
257
258#[unstable(feature = "bstr", issue = "134915")]
259impl<'a> From<ByteString> for Cow<'a, ByteStr> {
260    #[inline]
261    fn from(s: ByteString) -> Self {
262        Cow::Owned(s)
263    }
264}
265
266#[unstable(feature = "bstr", issue = "134915")]
267impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> {
268    #[inline]
269    fn from(s: &'a ByteString) -> Self {
270        Cow::Borrowed(s.as_bytestr())
271    }
272}
273
274#[unstable(feature = "bstr", issue = "134915")]
275impl FromIterator<char> for ByteString {
276    #[inline]
277    fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
278        ByteString(iter.into_iter().collect::<String>().into_bytes())
279    }
280}
281
282#[unstable(feature = "bstr", issue = "134915")]
283impl FromIterator<u8> for ByteString {
284    #[inline]
285    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
286        ByteString(iter.into_iter().collect())
287    }
288}
289
290#[unstable(feature = "bstr", issue = "134915")]
291impl<'a> FromIterator<&'a str> for ByteString {
292    #[inline]
293    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
294        ByteString(iter.into_iter().collect::<String>().into_bytes())
295    }
296}
297
298#[unstable(feature = "bstr", issue = "134915")]
299impl<'a> FromIterator<&'a [u8]> for ByteString {
300    #[inline]
301    fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> Self {
302        let mut buf = Vec::new();
303        for b in iter {
304            buf.extend_from_slice(b);
305        }
306        ByteString(buf)
307    }
308}
309
310#[unstable(feature = "bstr", issue = "134915")]
311impl<'a> FromIterator<&'a ByteStr> for ByteString {
312    #[inline]
313    fn from_iter<T: IntoIterator<Item = &'a ByteStr>>(iter: T) -> Self {
314        let mut buf = Vec::new();
315        for b in iter {
316            buf.extend_from_slice(&b.0);
317        }
318        ByteString(buf)
319    }
320}
321
322#[unstable(feature = "bstr", issue = "134915")]
323impl FromIterator<ByteString> for ByteString {
324    #[inline]
325    fn from_iter<T: IntoIterator<Item = ByteString>>(iter: T) -> Self {
326        let mut buf = Vec::new();
327        for mut b in iter {
328            buf.append(&mut b.0);
329        }
330        ByteString(buf)
331    }
332}
333
334#[unstable(feature = "bstr", issue = "134915")]
335impl FromStr for ByteString {
336    type Err = core::convert::Infallible;
337
338    #[inline]
339    fn from_str(s: &str) -> Result<Self, Self::Err> {
340        Ok(ByteString(s.as_bytes().to_vec()))
341    }
342}
343
344#[unstable(feature = "bstr", issue = "134915")]
345impl Index<usize> for ByteString {
346    type Output = u8;
347
348    #[inline]
349    fn index(&self, idx: usize) -> &u8 {
350        &self.0[idx]
351    }
352}
353
354#[unstable(feature = "bstr", issue = "134915")]
355impl Index<RangeFull> for ByteString {
356    type Output = ByteStr;
357
358    #[inline]
359    fn index(&self, _: RangeFull) -> &ByteStr {
360        self.as_bytestr()
361    }
362}
363
364#[unstable(feature = "bstr", issue = "134915")]
365impl Index<Range<usize>> for ByteString {
366    type Output = ByteStr;
367
368    #[inline]
369    fn index(&self, r: Range<usize>) -> &ByteStr {
370        ByteStr::from_bytes(&self.0[r])
371    }
372}
373
374#[unstable(feature = "bstr", issue = "134915")]
375impl Index<RangeInclusive<usize>> for ByteString {
376    type Output = ByteStr;
377
378    #[inline]
379    fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
380        ByteStr::from_bytes(&self.0[r])
381    }
382}
383
384#[unstable(feature = "bstr", issue = "134915")]
385impl Index<RangeFrom<usize>> for ByteString {
386    type Output = ByteStr;
387
388    #[inline]
389    fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
390        ByteStr::from_bytes(&self.0[r])
391    }
392}
393
394#[unstable(feature = "bstr", issue = "134915")]
395impl Index<RangeTo<usize>> for ByteString {
396    type Output = ByteStr;
397
398    #[inline]
399    fn index(&self, r: RangeTo<usize>) -> &ByteStr {
400        ByteStr::from_bytes(&self.0[r])
401    }
402}
403
404#[unstable(feature = "bstr", issue = "134915")]
405impl Index<RangeToInclusive<usize>> for ByteString {
406    type Output = ByteStr;
407
408    #[inline]
409    fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
410        ByteStr::from_bytes(&self.0[r])
411    }
412}
413
414#[unstable(feature = "bstr", issue = "134915")]
415impl IndexMut<usize> for ByteString {
416    #[inline]
417    fn index_mut(&mut self, idx: usize) -> &mut u8 {
418        &mut self.0[idx]
419    }
420}
421
422#[unstable(feature = "bstr", issue = "134915")]
423impl IndexMut<RangeFull> for ByteString {
424    #[inline]
425    fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
426        self.as_mut_bytestr()
427    }
428}
429
430#[unstable(feature = "bstr", issue = "134915")]
431impl IndexMut<Range<usize>> for ByteString {
432    #[inline]
433    fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
434        ByteStr::from_bytes_mut(&mut self.0[r])
435    }
436}
437
438#[unstable(feature = "bstr", issue = "134915")]
439impl IndexMut<RangeInclusive<usize>> for ByteString {
440    #[inline]
441    fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
442        ByteStr::from_bytes_mut(&mut self.0[r])
443    }
444}
445
446#[unstable(feature = "bstr", issue = "134915")]
447impl IndexMut<RangeFrom<usize>> for ByteString {
448    #[inline]
449    fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
450        ByteStr::from_bytes_mut(&mut self.0[r])
451    }
452}
453
454#[unstable(feature = "bstr", issue = "134915")]
455impl IndexMut<RangeTo<usize>> for ByteString {
456    #[inline]
457    fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
458        ByteStr::from_bytes_mut(&mut self.0[r])
459    }
460}
461
462#[unstable(feature = "bstr", issue = "134915")]
463impl IndexMut<RangeToInclusive<usize>> for ByteString {
464    #[inline]
465    fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
466        ByteStr::from_bytes_mut(&mut self.0[r])
467    }
468}
469
470#[unstable(feature = "bstr", issue = "134915")]
471impl hash::Hash for ByteString {
472    #[inline]
473    fn hash<H: hash::Hasher>(&self, state: &mut H) {
474        self.0.hash(state);
475    }
476}
477
478#[unstable(feature = "bstr", issue = "134915")]
479impl Eq for ByteString {}
480
481#[unstable(feature = "bstr", issue = "134915")]
482impl PartialEq for ByteString {
483    #[inline]
484    fn eq(&self, other: &ByteString) -> bool {
485        self.0 == other.0
486    }
487}
488
489macro_rules! impl_partial_eq_ord_cow {
490    ($lhs:ty, $rhs:ty) => {
491        #[unstable(feature = "bstr", issue = "134915")]
492        impl PartialEq<$rhs> for $lhs {
493            #[inline]
494            fn eq(&self, other: &$rhs) -> bool {
495                let other: &[u8] = (&**other).as_ref();
496                PartialEq::eq(self.as_bytes(), other)
497            }
498        }
499
500        #[unstable(feature = "bstr", issue = "134915")]
501        impl PartialEq<$lhs> for $rhs {
502            #[inline]
503            fn eq(&self, other: &$lhs) -> bool {
504                let this: &[u8] = (&**self).as_ref();
505                PartialEq::eq(this, other.as_bytes())
506            }
507        }
508
509        #[unstable(feature = "bstr", issue = "134915")]
510        impl PartialOrd<$rhs> for $lhs {
511            #[inline]
512            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
513                let other: &[u8] = (&**other).as_ref();
514                PartialOrd::partial_cmp(self.as_bytes(), other)
515            }
516        }
517
518        #[unstable(feature = "bstr", issue = "134915")]
519        impl PartialOrd<$lhs> for $rhs {
520            #[inline]
521            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
522                let this: &[u8] = (&**self).as_ref();
523                PartialOrd::partial_cmp(this, other.as_bytes())
524            }
525        }
526    };
527}
528
529// PartialOrd with `Vec<u8>` omitted to avoid inference failures
530impl PartialEq<Vec<u8>> for ByteString {
    #[inline]
    fn eq(&self, other: &Vec<u8>) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for Vec<u8> {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteString, Vec<u8>);
531// PartialOrd with `[u8]` omitted to avoid inference failures
532impl PartialEq<[u8]> for ByteString {
    #[inline]
    fn eq(&self, other: &[u8]) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for [u8] {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteString, [u8]);
533// PartialOrd with `&[u8]` omitted to avoid inference failures
534impl PartialEq<&[u8]> for ByteString {
    #[inline]
    fn eq(&self, other: &&[u8]) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for &[u8] {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteString, &[u8]);
535// PartialOrd with `String` omitted to avoid inference failures
536impl PartialEq<String> for ByteString {
    #[inline]
    fn eq(&self, other: &String) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for String {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteString, String);
537// PartialOrd with `str` omitted to avoid inference failures
538impl PartialEq<str> for ByteString {
    #[inline]
    fn eq(&self, other: &str) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for str {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteString, str);
539// PartialOrd with `&str` omitted to avoid inference failures
540impl PartialEq<&str> for ByteString {
    #[inline]
    fn eq(&self, other: &&str) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for &str {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteString, &str);
541impl PartialEq<ByteStr> for ByteString {
    #[inline]
    fn eq(&self, other: &ByteStr) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for ByteStr {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<ByteStr> for ByteString {
    #[inline]
    fn partial_cmp(&self, other: &ByteStr) -> Option<Ordering> {
        let other: &[u8] = other.as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<ByteString> for ByteStr {
    #[inline]
    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
        let this: &[u8] = self.as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord!(ByteString, ByteStr);
542impl PartialEq<&ByteStr> for ByteString {
    #[inline]
    fn eq(&self, other: &&ByteStr) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteString> for &ByteStr {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<&ByteStr> for ByteString {
    #[inline]
    fn partial_cmp(&self, other: &&ByteStr) -> Option<Ordering> {
        let other: &[u8] = other.as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<ByteString> for &ByteStr {
    #[inline]
    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
        let this: &[u8] = self.as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord!(ByteString, &ByteStr);
543// PartialOrd with `[u8; N]` omitted to avoid inference failures
544#[unstable(feature = "bstr", issue = "134915")]
impl<const N : usize> PartialEq<[u8; N]> for ByteString {
    #[inline]
    fn eq(&self, other: &[u8; N]) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl<const N : usize> PartialEq<ByteString> for [u8; N] {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq_n!(ByteString, [u8; N]);
545// PartialOrd with `&[u8; N]` omitted to avoid inference failures
546#[unstable(feature = "bstr", issue = "134915")]
impl<const N : usize> PartialEq<&[u8; N]> for ByteString {
    #[inline]
    fn eq(&self, other: &&[u8; N]) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl<const N : usize> PartialEq<ByteString> for &[u8; N] {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq_n!(ByteString, &[u8; N]);
547#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<Cow<'_, ByteStr>> for ByteString {
    #[inline]
    fn eq(&self, other: &Cow<'_, ByteStr>) -> bool {
        let other: &[u8] = (&**other).as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<ByteString> for Cow<'_, ByteStr> {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = (&**self).as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<Cow<'_, ByteStr>> for ByteString {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'_, ByteStr>) -> Option<Ordering> {
        let other: &[u8] = (&**other).as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<ByteString> for Cow<'_, ByteStr> {
    #[inline]
    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
        let this: &[u8] = (&**self).as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord_cow!(ByteString, Cow<'_, ByteStr>);
548#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<Cow<'_, str>> for ByteString {
    #[inline]
    fn eq(&self, other: &Cow<'_, str>) -> bool {
        let other: &[u8] = (&**other).as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<ByteString> for Cow<'_, str> {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = (&**self).as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<Cow<'_, str>> for ByteString {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
        let other: &[u8] = (&**other).as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<ByteString> for Cow<'_, str> {
    #[inline]
    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
        let this: &[u8] = (&**self).as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord_cow!(ByteString, Cow<'_, str>);
549#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<Cow<'_, [u8]>> for ByteString {
    #[inline]
    fn eq(&self, other: &Cow<'_, [u8]>) -> bool {
        let other: &[u8] = (&**other).as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<ByteString> for Cow<'_, [u8]> {
    #[inline]
    fn eq(&self, other: &ByteString) -> bool {
        let this: &[u8] = (&**self).as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<Cow<'_, [u8]>> for ByteString {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'_, [u8]>) -> Option<Ordering> {
        let other: &[u8] = (&**other).as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<ByteString> for Cow<'_, [u8]> {
    #[inline]
    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
        let this: &[u8] = (&**self).as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord_cow!(ByteString, Cow<'_, [u8]>);
550
551#[unstable(feature = "bstr", issue = "134915")]
552impl Ord for ByteString {
553    #[inline]
554    fn cmp(&self, other: &ByteString) -> Ordering {
555        Ord::cmp(&self.0, &other.0)
556    }
557}
558
559#[unstable(feature = "bstr", issue = "134915")]
560impl PartialOrd for ByteString {
561    #[inline]
562    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
563        PartialOrd::partial_cmp(&self.0, &other.0)
564    }
565}
566
567#[unstable(feature = "bstr", issue = "134915")]
568impl ToOwned for ByteStr {
569    type Owned = ByteString;
570
571    #[inline]
572    fn to_owned(&self) -> ByteString {
573        ByteString(self.0.to_vec())
574    }
575}
576
577#[unstable(feature = "bstr", issue = "134915")]
578impl TryFrom<ByteString> for String {
579    type Error = crate::string::FromUtf8Error;
580
581    #[inline]
582    fn try_from(s: ByteString) -> Result<Self, Self::Error> {
583        String::from_utf8(s.0)
584    }
585}
586
587#[unstable(feature = "bstr", issue = "134915")]
588impl<'a> TryFrom<&'a ByteString> for &'a str {
589    type Error = crate::str::Utf8Error;
590
591    #[inline]
592    fn try_from(s: &'a ByteString) -> Result<Self, Self::Error> {
593        crate::str::from_utf8(s.0.as_slice())
594    }
595}
596
597// Additional impls for `ByteStr` that require types from `alloc`:
598
599#[unstable(feature = "bstr", issue = "134915")]
600impl Clone for Box<ByteStr> {
601    #[inline]
602    fn clone(&self) -> Self {
603        Self::from(Box::<[u8]>::from(&self.0))
604    }
605}
606
607#[unstable(feature = "bstr", issue = "134915")]
608impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> {
609    #[inline]
610    fn from(s: &'a ByteStr) -> Self {
611        Cow::Borrowed(s)
612    }
613}
614
615#[unstable(feature = "bstr", issue = "134915")]
616impl From<Box<[u8]>> for Box<ByteStr> {
617    #[inline]
618    fn from(s: Box<[u8]>) -> Box<ByteStr> {
619        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
620        unsafe { Box::from_raw(Box::into_raw(s) as _) }
621    }
622}
623
624#[unstable(feature = "bstr", issue = "134915")]
625impl From<Box<ByteStr>> for Box<[u8]> {
626    #[inline]
627    fn from(s: Box<ByteStr>) -> Box<[u8]> {
628        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
629        unsafe { Box::from_raw(Box::into_raw(s) as _) }
630    }
631}
632
633#[unstable(feature = "bstr", issue = "134915")]
634#[cfg(not(no_rc))]
635impl From<Rc<[u8]>> for Rc<ByteStr> {
636    #[inline]
637    fn from(s: Rc<[u8]>) -> Rc<ByteStr> {
638        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
639        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
640    }
641}
642
643#[unstable(feature = "bstr", issue = "134915")]
644#[cfg(not(no_rc))]
645impl From<Rc<ByteStr>> for Rc<[u8]> {
646    #[inline]
647    fn from(s: Rc<ByteStr>) -> Rc<[u8]> {
648        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
649        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
650    }
651}
652
653#[unstable(feature = "bstr", issue = "134915")]
654#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
655impl From<Arc<[u8]>> for Arc<ByteStr> {
656    #[inline]
657    fn from(s: Arc<[u8]>) -> Arc<ByteStr> {
658        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
659        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
660    }
661}
662
663#[unstable(feature = "bstr", issue = "134915")]
664#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
665impl From<Arc<ByteStr>> for Arc<[u8]> {
666    #[inline]
667    fn from(s: Arc<ByteStr>) -> Arc<[u8]> {
668        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
669        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
670    }
671}
672
673// PartialOrd with `Vec<u8>` omitted to avoid inference failures
674impl PartialEq<Vec<u8>> for ByteStr {
    #[inline]
    fn eq(&self, other: &Vec<u8>) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteStr> for Vec<u8> {
    #[inline]
    fn eq(&self, other: &ByteStr) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteStr, Vec<u8>);
675// PartialOrd with `String` omitted to avoid inference failures
676impl PartialEq<String> for ByteStr {
    #[inline]
    fn eq(&self, other: &String) -> bool {
        let other: &[u8] = other.as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
impl PartialEq<ByteStr> for String {
    #[inline]
    fn eq(&self, other: &ByteStr) -> bool {
        let this: &[u8] = self.as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}impl_partial_eq!(ByteStr, String);
677#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<Cow<'_, ByteStr>> for &ByteStr {
    #[inline]
    fn eq(&self, other: &Cow<'_, ByteStr>) -> bool {
        let other: &[u8] = (&**other).as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<&ByteStr> for Cow<'_, ByteStr> {
    #[inline]
    fn eq(&self, other: &&ByteStr) -> bool {
        let this: &[u8] = (&**self).as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<Cow<'_, ByteStr>> for &ByteStr {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'_, ByteStr>) -> Option<Ordering> {
        let other: &[u8] = (&**other).as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<&ByteStr> for Cow<'_, ByteStr> {
    #[inline]
    fn partial_cmp(&self, other: &&ByteStr) -> Option<Ordering> {
        let this: &[u8] = (&**self).as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, ByteStr>);
678#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<Cow<'_, str>> for &ByteStr {
    #[inline]
    fn eq(&self, other: &Cow<'_, str>) -> bool {
        let other: &[u8] = (&**other).as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<&ByteStr> for Cow<'_, str> {
    #[inline]
    fn eq(&self, other: &&ByteStr) -> bool {
        let this: &[u8] = (&**self).as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<Cow<'_, str>> for &ByteStr {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'_, str>) -> Option<Ordering> {
        let other: &[u8] = (&**other).as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<&ByteStr> for Cow<'_, str> {
    #[inline]
    fn partial_cmp(&self, other: &&ByteStr) -> Option<Ordering> {
        let this: &[u8] = (&**self).as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, str>);
679#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<Cow<'_, [u8]>> for &ByteStr {
    #[inline]
    fn eq(&self, other: &Cow<'_, [u8]>) -> bool {
        let other: &[u8] = (&**other).as_ref();
        PartialEq::eq(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialEq<&ByteStr> for Cow<'_, [u8]> {
    #[inline]
    fn eq(&self, other: &&ByteStr) -> bool {
        let this: &[u8] = (&**self).as_ref();
        PartialEq::eq(this, other.as_bytes())
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<Cow<'_, [u8]>> for &ByteStr {
    #[inline]
    fn partial_cmp(&self, other: &Cow<'_, [u8]>) -> Option<Ordering> {
        let other: &[u8] = (&**other).as_ref();
        PartialOrd::partial_cmp(self.as_bytes(), other)
    }
}
#[unstable(feature = "bstr", issue = "134915")]
impl PartialOrd<&ByteStr> for Cow<'_, [u8]> {
    #[inline]
    fn partial_cmp(&self, other: &&ByteStr) -> Option<Ordering> {
        let this: &[u8] = (&**self).as_ref();
        PartialOrd::partial_cmp(this, other.as_bytes())
    }
}impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, [u8]>);
680
681#[unstable(feature = "bstr", issue = "134915")]
682impl<'a> TryFrom<&'a ByteStr> for String {
683    type Error = core::str::Utf8Error;
684
685    #[inline]
686    fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
687        Ok(core::str::from_utf8(&s.0)?.into())
688    }
689}
690
691impl ByteStr {
692    /// Try to get a `String` representation of the `&ByteStr`, if it is valid
693    /// UTF-8.
694    ///
695    /// This method is named `to_string()` because we want `ByteStr` to
696    /// implement `Display`, but the `ToString` trait has a blanket
697    /// implementation for types that implement `Display`, and the trait version
698    /// will use the Unicode replacement character rather than returning a
699    /// `Result` and allowing for the possibility of the content not being UTF-8.
700    #[unstable(feature = "bstr_to_string", issue = "134915")]
701    #[rustc_allow_incoherent_impl]
702    pub fn to_string(&self) -> Result<String, Utf8Error> {
703        // Avoid allocating a copy of the contents for invalid UTF-8
704        if let Err(e) = str::from_utf8(&self.0) {
705            return Err(e);
706        }
707        // SAFETY: we just checked that the contents are valid UTF-8
708        Ok(unsafe { String::from_utf8_unchecked(self.0.to_vec()) })
709    }
710}