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};
15#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
16use core::str::FromStr;
17use core::{fmt, hash};
18
19#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
20use crate::borrow::{Cow, ToOwned};
21#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
22use crate::boxed::Box;
23#[cfg(not(no_rc))]
24use crate::rc::Rc;
25use crate::string::String;
26#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
27use crate::sync::Arc;
28use crate::vec::Vec;
29
30/// A wrapper for `Vec<u8>` representing a human-readable string that's conventionally, but not
31/// always, UTF-8.
32///
33/// Unlike `String`, this type permits non-UTF-8 contents, making it suitable for user input,
34/// non-native filenames (as `Path` only supports native filenames), and other applications that
35/// need to round-trip whatever data the user provides.
36///
37/// A `ByteString` owns its contents and can grow and shrink, like a `Vec` or `String`. For a
38/// borrowed byte string, see [`ByteStr`](../../std/bstr/struct.ByteStr.html).
39///
40/// `ByteString` implements `Deref` to `&Vec<u8>`, so all methods available on `&Vec<u8>` are
41/// available on `ByteString`. Similarly, `ByteString` implements `DerefMut` to `&mut Vec<u8>`,
42/// so you can modify a `ByteString` using any method available on `&mut Vec<u8>`.
43///
44/// The `Debug` and `Display` implementations for `ByteString` are the same as those for `ByteStr`,
45/// showing invalid UTF-8 as hex escapes or the Unicode replacement character, respectively.
46#[unstable(feature = "bstr", issue = "134915")]
47#[repr(transparent)]
48#[derive(Clone)]
49#[doc(alias = "BString")]
50pub struct ByteString(pub Vec<u8>);
51
52impl ByteString {
53    #[inline]
54    pub(crate) fn as_bytes(&self) -> &[u8] {
55        &self.0
56    }
57
58    #[inline]
59    pub(crate) fn as_bytestr(&self) -> &ByteStr {
60        ByteStr::new(&self.0)
61    }
62
63    #[inline]
64    pub(crate) fn as_mut_bytestr(&mut self) -> &mut ByteStr {
65        ByteStr::from_bytes_mut(&mut self.0)
66    }
67}
68
69#[unstable(feature = "bstr", issue = "134915")]
70impl Deref for ByteString {
71    type Target = Vec<u8>;
72
73    #[inline]
74    fn deref(&self) -> &Self::Target {
75        &self.0
76    }
77}
78
79#[unstable(feature = "bstr", issue = "134915")]
80impl DerefMut for ByteString {
81    #[inline]
82    fn deref_mut(&mut self) -> &mut Self::Target {
83        &mut self.0
84    }
85}
86
87#[unstable(feature = "deref_pure_trait", issue = "87121")]
88unsafe impl DerefPure for ByteString {}
89
90#[unstable(feature = "bstr", issue = "134915")]
91impl fmt::Debug for ByteString {
92    #[inline]
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        fmt::Debug::fmt(self.as_bytestr(), f)
95    }
96}
97
98#[unstable(feature = "bstr", issue = "134915")]
99impl fmt::Display for ByteString {
100    #[inline]
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        fmt::Display::fmt(self.as_bytestr(), f)
103    }
104}
105
106#[unstable(feature = "bstr", issue = "134915")]
107impl AsRef<[u8]> for ByteString {
108    #[inline]
109    fn as_ref(&self) -> &[u8] {
110        &self.0
111    }
112}
113
114#[unstable(feature = "bstr", issue = "134915")]
115impl AsRef<ByteStr> for ByteString {
116    #[inline]
117    fn as_ref(&self) -> &ByteStr {
118        self.as_bytestr()
119    }
120}
121
122#[unstable(feature = "bstr", issue = "134915")]
123impl AsMut<[u8]> for ByteString {
124    #[inline]
125    fn as_mut(&mut self) -> &mut [u8] {
126        &mut self.0
127    }
128}
129
130#[unstable(feature = "bstr", issue = "134915")]
131impl AsMut<ByteStr> for ByteString {
132    #[inline]
133    fn as_mut(&mut self) -> &mut ByteStr {
134        self.as_mut_bytestr()
135    }
136}
137
138#[unstable(feature = "bstr", issue = "134915")]
139impl Borrow<[u8]> for ByteString {
140    #[inline]
141    fn borrow(&self) -> &[u8] {
142        &self.0
143    }
144}
145
146#[unstable(feature = "bstr", issue = "134915")]
147impl Borrow<ByteStr> for ByteString {
148    #[inline]
149    fn borrow(&self) -> &ByteStr {
150        self.as_bytestr()
151    }
152}
153
154// `impl Borrow<ByteStr> for Vec<u8>` omitted to avoid inference failures
155// `impl Borrow<ByteStr> for String` omitted to avoid inference failures
156
157#[unstable(feature = "bstr", issue = "134915")]
158impl BorrowMut<[u8]> for ByteString {
159    #[inline]
160    fn borrow_mut(&mut self) -> &mut [u8] {
161        &mut self.0
162    }
163}
164
165#[unstable(feature = "bstr", issue = "134915")]
166impl BorrowMut<ByteStr> for ByteString {
167    #[inline]
168    fn borrow_mut(&mut self) -> &mut ByteStr {
169        self.as_mut_bytestr()
170    }
171}
172
173// `impl BorrowMut<ByteStr> for Vec<u8>` omitted to avoid inference failures
174
175#[unstable(feature = "bstr", issue = "134915")]
176impl Default for ByteString {
177    fn default() -> Self {
178        ByteString(Vec::new())
179    }
180}
181
182// Omitted due to inference failures
183//
184// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
185// #[unstable(feature = "bstr", issue = "134915")]
186// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString {
187//     #[inline]
188//     fn from(s: &'a [u8; N]) -> Self {
189//         ByteString(s.as_slice().to_vec())
190//     }
191// }
192//
193// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
194// #[unstable(feature = "bstr", issue = "134915")]
195// impl<const N: usize> From<[u8; N]> for ByteString {
196//     #[inline]
197//     fn from(s: [u8; N]) -> Self {
198//         ByteString(s.as_slice().to_vec())
199//     }
200// }
201//
202// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
203// #[unstable(feature = "bstr", issue = "134915")]
204// impl<'a> From<&'a [u8]> for ByteString {
205//     #[inline]
206//     fn from(s: &'a [u8]) -> Self {
207//         ByteString(s.to_vec())
208//     }
209// }
210//
211// #[unstable(feature = "bstr", issue = "134915")]
212// impl From<Vec<u8>> for ByteString {
213//     #[inline]
214//     fn from(s: Vec<u8>) -> Self {
215//         ByteString(s)
216//     }
217// }
218
219#[unstable(feature = "bstr", issue = "134915")]
220impl From<ByteString> for Vec<u8> {
221    #[inline]
222    fn from(s: ByteString) -> Self {
223        s.0
224    }
225}
226
227// Omitted due to inference failures
228//
229// #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
230// #[unstable(feature = "bstr", issue = "134915")]
231// impl<'a> From<&'a str> for ByteString {
232//     #[inline]
233//     fn from(s: &'a str) -> Self {
234//         ByteString(s.as_bytes().to_vec())
235//     }
236// }
237//
238// #[unstable(feature = "bstr", issue = "134915")]
239// impl From<String> for ByteString {
240//     #[inline]
241//     fn from(s: String) -> Self {
242//         ByteString(s.into_bytes())
243//     }
244// }
245
246#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
247#[unstable(feature = "bstr", issue = "134915")]
248impl<'a> From<&'a ByteStr> for ByteString {
249    #[inline]
250    fn from(s: &'a ByteStr) -> Self {
251        ByteString(s.0.to_vec())
252    }
253}
254
255#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
256#[unstable(feature = "bstr", issue = "134915")]
257impl<'a> From<ByteString> for Cow<'a, ByteStr> {
258    #[inline]
259    fn from(s: ByteString) -> Self {
260        Cow::Owned(s)
261    }
262}
263
264#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
265#[unstable(feature = "bstr", issue = "134915")]
266impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> {
267    #[inline]
268    fn from(s: &'a ByteString) -> Self {
269        Cow::Borrowed(s.as_bytestr())
270    }
271}
272
273#[unstable(feature = "bstr", issue = "134915")]
274impl FromIterator<char> for ByteString {
275    #[inline]
276    fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
277        ByteString(iter.into_iter().collect::<String>().into_bytes())
278    }
279}
280
281#[unstable(feature = "bstr", issue = "134915")]
282impl FromIterator<u8> for ByteString {
283    #[inline]
284    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
285        ByteString(iter.into_iter().collect())
286    }
287}
288
289#[unstable(feature = "bstr", issue = "134915")]
290impl<'a> FromIterator<&'a str> for ByteString {
291    #[inline]
292    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
293        ByteString(iter.into_iter().collect::<String>().into_bytes())
294    }
295}
296
297#[unstable(feature = "bstr", issue = "134915")]
298impl<'a> FromIterator<&'a [u8]> for ByteString {
299    #[inline]
300    fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> Self {
301        let mut buf = Vec::new();
302        for b in iter {
303            buf.extend_from_slice(b);
304        }
305        ByteString(buf)
306    }
307}
308
309#[unstable(feature = "bstr", issue = "134915")]
310impl<'a> FromIterator<&'a ByteStr> for ByteString {
311    #[inline]
312    fn from_iter<T: IntoIterator<Item = &'a ByteStr>>(iter: T) -> Self {
313        let mut buf = Vec::new();
314        for b in iter {
315            buf.extend_from_slice(&b.0);
316        }
317        ByteString(buf)
318    }
319}
320
321#[unstable(feature = "bstr", issue = "134915")]
322impl FromIterator<ByteString> for ByteString {
323    #[inline]
324    fn from_iter<T: IntoIterator<Item = ByteString>>(iter: T) -> Self {
325        let mut buf = Vec::new();
326        for mut b in iter {
327            buf.append(&mut b.0);
328        }
329        ByteString(buf)
330    }
331}
332
333#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
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        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
492        #[allow(unused_lifetimes)]
493        #[unstable(feature = "bstr", issue = "134915")]
494        impl<'a> PartialEq<$rhs> for $lhs {
495            #[inline]
496            fn eq(&self, other: &$rhs) -> bool {
497                let other: &[u8] = (&**other).as_ref();
498                PartialEq::eq(self.as_bytes(), other)
499            }
500        }
501
502        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
503        #[allow(unused_lifetimes)]
504        #[unstable(feature = "bstr", issue = "134915")]
505        impl<'a> PartialEq<$lhs> for $rhs {
506            #[inline]
507            fn eq(&self, other: &$lhs) -> bool {
508                let this: &[u8] = (&**self).as_ref();
509                PartialEq::eq(this, other.as_bytes())
510            }
511        }
512
513        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
514        #[allow(unused_lifetimes)]
515        #[unstable(feature = "bstr", issue = "134915")]
516        impl<'a> PartialOrd<$rhs> for $lhs {
517            #[inline]
518            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
519                let other: &[u8] = (&**other).as_ref();
520                PartialOrd::partial_cmp(self.as_bytes(), other)
521            }
522        }
523
524        #[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
525        #[allow(unused_lifetimes)]
526        #[unstable(feature = "bstr", issue = "134915")]
527        impl<'a> PartialOrd<$lhs> for $rhs {
528            #[inline]
529            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
530                let this: &[u8] = (&**self).as_ref();
531                PartialOrd::partial_cmp(this, other.as_bytes())
532            }
533        }
534    };
535}
536
537// PartialOrd with `Vec<u8>` omitted to avoid inference failures
538impl_partial_eq!(ByteString, Vec<u8>);
539// PartialOrd with `[u8]` omitted to avoid inference failures
540impl_partial_eq!(ByteString, [u8]);
541// PartialOrd with `&[u8]` omitted to avoid inference failures
542impl_partial_eq!(ByteString, &[u8]);
543// PartialOrd with `String` omitted to avoid inference failures
544impl_partial_eq!(ByteString, String);
545// PartialOrd with `str` omitted to avoid inference failures
546impl_partial_eq!(ByteString, str);
547// PartialOrd with `&str` omitted to avoid inference failures
548impl_partial_eq!(ByteString, &str);
549impl_partial_eq_ord!(ByteString, ByteStr);
550impl_partial_eq_ord!(ByteString, &ByteStr);
551// PartialOrd with `[u8; N]` omitted to avoid inference failures
552impl_partial_eq_n!(ByteString, [u8; N]);
553// PartialOrd with `&[u8; N]` omitted to avoid inference failures
554impl_partial_eq_n!(ByteString, &[u8; N]);
555impl_partial_eq_ord_cow!(ByteString, Cow<'_, ByteStr>);
556impl_partial_eq_ord_cow!(ByteString, Cow<'_, str>);
557impl_partial_eq_ord_cow!(ByteString, Cow<'_, [u8]>);
558
559#[unstable(feature = "bstr", issue = "134915")]
560impl Ord for ByteString {
561    #[inline]
562    fn cmp(&self, other: &ByteString) -> Ordering {
563        Ord::cmp(&self.0, &other.0)
564    }
565}
566
567#[unstable(feature = "bstr", issue = "134915")]
568impl PartialOrd for ByteString {
569    #[inline]
570    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
571        PartialOrd::partial_cmp(&self.0, &other.0)
572    }
573}
574
575#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
576#[unstable(feature = "bstr", issue = "134915")]
577impl ToOwned for ByteStr {
578    type Owned = ByteString;
579
580    #[inline]
581    fn to_owned(&self) -> ByteString {
582        ByteString(self.0.to_vec())
583    }
584}
585
586#[unstable(feature = "bstr", issue = "134915")]
587impl TryFrom<ByteString> for String {
588    type Error = crate::string::FromUtf8Error;
589
590    #[inline]
591    fn try_from(s: ByteString) -> Result<Self, Self::Error> {
592        String::from_utf8(s.0)
593    }
594}
595
596#[unstable(feature = "bstr", issue = "134915")]
597impl<'a> TryFrom<&'a ByteString> for &'a str {
598    type Error = crate::str::Utf8Error;
599
600    #[inline]
601    fn try_from(s: &'a ByteString) -> Result<Self, Self::Error> {
602        crate::str::from_utf8(s.0.as_slice())
603    }
604}
605
606// Additional impls for `ByteStr` that require types from `alloc`:
607
608#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
609#[unstable(feature = "bstr", issue = "134915")]
610impl Clone for Box<ByteStr> {
611    #[inline]
612    fn clone(&self) -> Self {
613        Self::from(Box::<[u8]>::from(&self.0))
614    }
615}
616
617#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
618#[unstable(feature = "bstr", issue = "134915")]
619impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> {
620    #[inline]
621    fn from(s: &'a ByteStr) -> Self {
622        Cow::Borrowed(s)
623    }
624}
625
626#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
627#[unstable(feature = "bstr", issue = "134915")]
628impl From<Box<[u8]>> for Box<ByteStr> {
629    #[inline]
630    fn from(s: Box<[u8]>) -> Box<ByteStr> {
631        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
632        unsafe { Box::from_raw(Box::into_raw(s) as _) }
633    }
634}
635
636#[cfg(not(test))] // https://github.com/rust-lang/rust/issues/135100
637#[unstable(feature = "bstr", issue = "134915")]
638impl From<Box<ByteStr>> for Box<[u8]> {
639    #[inline]
640    fn from(s: Box<ByteStr>) -> Box<[u8]> {
641        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
642        unsafe { Box::from_raw(Box::into_raw(s) as _) }
643    }
644}
645
646#[unstable(feature = "bstr", issue = "134915")]
647#[cfg(not(no_rc))]
648impl From<Rc<[u8]>> for Rc<ByteStr> {
649    #[inline]
650    fn from(s: Rc<[u8]>) -> Rc<ByteStr> {
651        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
652        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
653    }
654}
655
656#[unstable(feature = "bstr", issue = "134915")]
657#[cfg(not(no_rc))]
658impl From<Rc<ByteStr>> for Rc<[u8]> {
659    #[inline]
660    fn from(s: Rc<ByteStr>) -> Rc<[u8]> {
661        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
662        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
663    }
664}
665
666#[unstable(feature = "bstr", issue = "134915")]
667#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
668impl From<Arc<[u8]>> for Arc<ByteStr> {
669    #[inline]
670    fn from(s: Arc<[u8]>) -> Arc<ByteStr> {
671        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
672        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
673    }
674}
675
676#[unstable(feature = "bstr", issue = "134915")]
677#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
678impl From<Arc<ByteStr>> for Arc<[u8]> {
679    #[inline]
680    fn from(s: Arc<ByteStr>) -> Arc<[u8]> {
681        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
682        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
683    }
684}
685
686// PartialOrd with `Vec<u8>` omitted to avoid inference failures
687impl_partial_eq!(ByteStr, Vec<u8>);
688// PartialOrd with `String` omitted to avoid inference failures
689impl_partial_eq!(ByteStr, String);
690impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, ByteStr>);
691impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, str>);
692impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, [u8]>);
693
694#[unstable(feature = "bstr", issue = "134915")]
695impl<'a> TryFrom<&'a ByteStr> for String {
696    type Error = core::str::Utf8Error;
697
698    #[inline]
699    fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
700        Ok(core::str::from_utf8(&s.0)?.into())
701    }
702}