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(Clone)]
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#[unstable(feature = "bstr", issue = "134915")]
191impl Default for ByteString {
192    fn default() -> Self {
193        ByteString(Vec::new())
194    }
195}
196
197// Omitted due to inference failures
198//
199// #[unstable(feature = "bstr", issue = "134915")]
200// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString {
201//     #[inline]
202//     fn from(s: &'a [u8; N]) -> Self {
203//         ByteString(s.as_slice().to_vec())
204//     }
205// }
206//
207// #[unstable(feature = "bstr", issue = "134915")]
208// impl<const N: usize> From<[u8; N]> for ByteString {
209//     #[inline]
210//     fn from(s: [u8; N]) -> Self {
211//         ByteString(s.as_slice().to_vec())
212//     }
213// }
214//
215// #[unstable(feature = "bstr", issue = "134915")]
216// impl<'a> From<&'a [u8]> for ByteString {
217//     #[inline]
218//     fn from(s: &'a [u8]) -> Self {
219//         ByteString(s.to_vec())
220//     }
221// }
222//
223// #[unstable(feature = "bstr", issue = "134915")]
224// impl From<Vec<u8>> for ByteString {
225//     #[inline]
226//     fn from(s: Vec<u8>) -> Self {
227//         ByteString(s)
228//     }
229// }
230
231#[unstable(feature = "bstr", issue = "134915")]
232impl From<ByteString> for Vec<u8> {
233    #[inline]
234    fn from(s: ByteString) -> Self {
235        s.0
236    }
237}
238
239// Omitted due to inference failures
240//
241// #[unstable(feature = "bstr", issue = "134915")]
242// impl<'a> From<&'a str> for ByteString {
243//     #[inline]
244//     fn from(s: &'a str) -> Self {
245//         ByteString(s.as_bytes().to_vec())
246//     }
247// }
248//
249// #[unstable(feature = "bstr", issue = "134915")]
250// impl From<String> for ByteString {
251//     #[inline]
252//     fn from(s: String) -> Self {
253//         ByteString(s.into_bytes())
254//     }
255// }
256
257#[unstable(feature = "bstr", issue = "134915")]
258impl<'a> From<&'a ByteStr> for ByteString {
259    #[inline]
260    fn from(s: &'a ByteStr) -> Self {
261        ByteString(s.0.to_vec())
262    }
263}
264
265#[unstable(feature = "bstr", issue = "134915")]
266impl<'a> From<ByteString> for Cow<'a, ByteStr> {
267    #[inline]
268    fn from(s: ByteString) -> Self {
269        Cow::Owned(s)
270    }
271}
272
273#[unstable(feature = "bstr", issue = "134915")]
274impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> {
275    #[inline]
276    fn from(s: &'a ByteString) -> Self {
277        Cow::Borrowed(s.as_bytestr())
278    }
279}
280
281#[unstable(feature = "bstr", issue = "134915")]
282impl FromIterator<char> for ByteString {
283    #[inline]
284    fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
285        ByteString(iter.into_iter().collect::<String>().into_bytes())
286    }
287}
288
289#[unstable(feature = "bstr", issue = "134915")]
290impl FromIterator<u8> for ByteString {
291    #[inline]
292    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
293        ByteString(iter.into_iter().collect())
294    }
295}
296
297#[unstable(feature = "bstr", issue = "134915")]
298impl<'a> FromIterator<&'a str> for ByteString {
299    #[inline]
300    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
301        ByteString(iter.into_iter().collect::<String>().into_bytes())
302    }
303}
304
305#[unstable(feature = "bstr", issue = "134915")]
306impl<'a> FromIterator<&'a [u8]> for ByteString {
307    #[inline]
308    fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> Self {
309        let mut buf = Vec::new();
310        for b in iter {
311            buf.extend_from_slice(b);
312        }
313        ByteString(buf)
314    }
315}
316
317#[unstable(feature = "bstr", issue = "134915")]
318impl<'a> FromIterator<&'a ByteStr> for ByteString {
319    #[inline]
320    fn from_iter<T: IntoIterator<Item = &'a ByteStr>>(iter: T) -> Self {
321        let mut buf = Vec::new();
322        for b in iter {
323            buf.extend_from_slice(&b.0);
324        }
325        ByteString(buf)
326    }
327}
328
329#[unstable(feature = "bstr", issue = "134915")]
330impl FromIterator<ByteString> for ByteString {
331    #[inline]
332    fn from_iter<T: IntoIterator<Item = ByteString>>(iter: T) -> Self {
333        let mut buf = Vec::new();
334        for mut b in iter {
335            buf.append(&mut b.0);
336        }
337        ByteString(buf)
338    }
339}
340
341#[unstable(feature = "bstr", issue = "134915")]
342impl FromStr for ByteString {
343    type Err = core::convert::Infallible;
344
345    #[inline]
346    fn from_str(s: &str) -> Result<Self, Self::Err> {
347        Ok(ByteString(s.as_bytes().to_vec()))
348    }
349}
350
351#[unstable(feature = "bstr", issue = "134915")]
352impl Index<usize> for ByteString {
353    type Output = u8;
354
355    #[inline]
356    fn index(&self, idx: usize) -> &u8 {
357        &self.0[idx]
358    }
359}
360
361#[unstable(feature = "bstr", issue = "134915")]
362impl Index<RangeFull> for ByteString {
363    type Output = ByteStr;
364
365    #[inline]
366    fn index(&self, _: RangeFull) -> &ByteStr {
367        self.as_bytestr()
368    }
369}
370
371#[unstable(feature = "bstr", issue = "134915")]
372impl Index<Range<usize>> for ByteString {
373    type Output = ByteStr;
374
375    #[inline]
376    fn index(&self, r: Range<usize>) -> &ByteStr {
377        ByteStr::from_bytes(&self.0[r])
378    }
379}
380
381#[unstable(feature = "bstr", issue = "134915")]
382impl Index<RangeInclusive<usize>> for ByteString {
383    type Output = ByteStr;
384
385    #[inline]
386    fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
387        ByteStr::from_bytes(&self.0[r])
388    }
389}
390
391#[unstable(feature = "bstr", issue = "134915")]
392impl Index<RangeFrom<usize>> for ByteString {
393    type Output = ByteStr;
394
395    #[inline]
396    fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
397        ByteStr::from_bytes(&self.0[r])
398    }
399}
400
401#[unstable(feature = "bstr", issue = "134915")]
402impl Index<RangeTo<usize>> for ByteString {
403    type Output = ByteStr;
404
405    #[inline]
406    fn index(&self, r: RangeTo<usize>) -> &ByteStr {
407        ByteStr::from_bytes(&self.0[r])
408    }
409}
410
411#[unstable(feature = "bstr", issue = "134915")]
412impl Index<RangeToInclusive<usize>> for ByteString {
413    type Output = ByteStr;
414
415    #[inline]
416    fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
417        ByteStr::from_bytes(&self.0[r])
418    }
419}
420
421#[unstable(feature = "bstr", issue = "134915")]
422impl IndexMut<usize> for ByteString {
423    #[inline]
424    fn index_mut(&mut self, idx: usize) -> &mut u8 {
425        &mut self.0[idx]
426    }
427}
428
429#[unstable(feature = "bstr", issue = "134915")]
430impl IndexMut<RangeFull> for ByteString {
431    #[inline]
432    fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
433        self.as_mut_bytestr()
434    }
435}
436
437#[unstable(feature = "bstr", issue = "134915")]
438impl IndexMut<Range<usize>> for ByteString {
439    #[inline]
440    fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
441        ByteStr::from_bytes_mut(&mut self.0[r])
442    }
443}
444
445#[unstable(feature = "bstr", issue = "134915")]
446impl IndexMut<RangeInclusive<usize>> for ByteString {
447    #[inline]
448    fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
449        ByteStr::from_bytes_mut(&mut self.0[r])
450    }
451}
452
453#[unstable(feature = "bstr", issue = "134915")]
454impl IndexMut<RangeFrom<usize>> for ByteString {
455    #[inline]
456    fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
457        ByteStr::from_bytes_mut(&mut self.0[r])
458    }
459}
460
461#[unstable(feature = "bstr", issue = "134915")]
462impl IndexMut<RangeTo<usize>> for ByteString {
463    #[inline]
464    fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
465        ByteStr::from_bytes_mut(&mut self.0[r])
466    }
467}
468
469#[unstable(feature = "bstr", issue = "134915")]
470impl IndexMut<RangeToInclusive<usize>> for ByteString {
471    #[inline]
472    fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
473        ByteStr::from_bytes_mut(&mut self.0[r])
474    }
475}
476
477#[unstable(feature = "bstr", issue = "134915")]
478impl hash::Hash for ByteString {
479    #[inline]
480    fn hash<H: hash::Hasher>(&self, state: &mut H) {
481        self.0.hash(state);
482    }
483}
484
485#[unstable(feature = "bstr", issue = "134915")]
486impl Eq for ByteString {}
487
488#[unstable(feature = "bstr", issue = "134915")]
489impl PartialEq for ByteString {
490    #[inline]
491    fn eq(&self, other: &ByteString) -> bool {
492        self.0 == other.0
493    }
494}
495
496macro_rules! impl_partial_eq_ord_cow {
497    ($lhs:ty, $rhs:ty) => {
498        #[unstable(feature = "bstr", issue = "134915")]
499        impl PartialEq<$rhs> for $lhs {
500            #[inline]
501            fn eq(&self, other: &$rhs) -> bool {
502                let other: &[u8] = (&**other).as_ref();
503                PartialEq::eq(self.as_bytes(), other)
504            }
505        }
506
507        #[unstable(feature = "bstr", issue = "134915")]
508        impl PartialEq<$lhs> for $rhs {
509            #[inline]
510            fn eq(&self, other: &$lhs) -> bool {
511                let this: &[u8] = (&**self).as_ref();
512                PartialEq::eq(this, other.as_bytes())
513            }
514        }
515
516        #[unstable(feature = "bstr", issue = "134915")]
517        impl PartialOrd<$rhs> for $lhs {
518            #[inline]
519            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
520                let other: &[u8] = (&**other).as_ref();
521                PartialOrd::partial_cmp(self.as_bytes(), other)
522            }
523        }
524
525        #[unstable(feature = "bstr", issue = "134915")]
526        impl PartialOrd<$lhs> for $rhs {
527            #[inline]
528            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
529                let this: &[u8] = (&**self).as_ref();
530                PartialOrd::partial_cmp(this, other.as_bytes())
531            }
532        }
533    };
534}
535
536// PartialOrd with `Vec<u8>` omitted to avoid inference failures
537impl_partial_eq!(ByteString, Vec<u8>);
538// PartialOrd with `[u8]` omitted to avoid inference failures
539impl_partial_eq!(ByteString, [u8]);
540// PartialOrd with `&[u8]` omitted to avoid inference failures
541impl_partial_eq!(ByteString, &[u8]);
542// PartialOrd with `String` omitted to avoid inference failures
543impl_partial_eq!(ByteString, String);
544// PartialOrd with `str` omitted to avoid inference failures
545impl_partial_eq!(ByteString, str);
546// PartialOrd with `&str` omitted to avoid inference failures
547impl_partial_eq!(ByteString, &str);
548impl_partial_eq_ord!(ByteString, ByteStr);
549impl_partial_eq_ord!(ByteString, &ByteStr);
550// PartialOrd with `[u8; N]` omitted to avoid inference failures
551impl_partial_eq_n!(ByteString, [u8; N]);
552// PartialOrd with `&[u8; N]` omitted to avoid inference failures
553impl_partial_eq_n!(ByteString, &[u8; N]);
554impl_partial_eq_ord_cow!(ByteString, Cow<'_, ByteStr>);
555impl_partial_eq_ord_cow!(ByteString, Cow<'_, str>);
556impl_partial_eq_ord_cow!(ByteString, Cow<'_, [u8]>);
557
558#[unstable(feature = "bstr", issue = "134915")]
559impl Ord for ByteString {
560    #[inline]
561    fn cmp(&self, other: &ByteString) -> Ordering {
562        Ord::cmp(&self.0, &other.0)
563    }
564}
565
566#[unstable(feature = "bstr", issue = "134915")]
567impl PartialOrd for ByteString {
568    #[inline]
569    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
570        PartialOrd::partial_cmp(&self.0, &other.0)
571    }
572}
573
574#[unstable(feature = "bstr", issue = "134915")]
575impl ToOwned for ByteStr {
576    type Owned = ByteString;
577
578    #[inline]
579    fn to_owned(&self) -> ByteString {
580        ByteString(self.0.to_vec())
581    }
582}
583
584#[unstable(feature = "bstr", issue = "134915")]
585impl TryFrom<ByteString> for String {
586    type Error = crate::string::FromUtf8Error;
587
588    #[inline]
589    fn try_from(s: ByteString) -> Result<Self, Self::Error> {
590        String::from_utf8(s.0)
591    }
592}
593
594#[unstable(feature = "bstr", issue = "134915")]
595impl<'a> TryFrom<&'a ByteString> for &'a str {
596    type Error = crate::str::Utf8Error;
597
598    #[inline]
599    fn try_from(s: &'a ByteString) -> Result<Self, Self::Error> {
600        crate::str::from_utf8(s.0.as_slice())
601    }
602}
603
604// Additional impls for `ByteStr` that require types from `alloc`:
605
606#[unstable(feature = "bstr", issue = "134915")]
607impl Clone for Box<ByteStr> {
608    #[inline]
609    fn clone(&self) -> Self {
610        Self::from(Box::<[u8]>::from(&self.0))
611    }
612}
613
614#[unstable(feature = "bstr", issue = "134915")]
615impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> {
616    #[inline]
617    fn from(s: &'a ByteStr) -> Self {
618        Cow::Borrowed(s)
619    }
620}
621
622#[unstable(feature = "bstr", issue = "134915")]
623impl From<Box<[u8]>> for Box<ByteStr> {
624    #[inline]
625    fn from(s: Box<[u8]>) -> Box<ByteStr> {
626        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
627        unsafe { Box::from_raw(Box::into_raw(s) as _) }
628    }
629}
630
631#[unstable(feature = "bstr", issue = "134915")]
632impl From<Box<ByteStr>> for Box<[u8]> {
633    #[inline]
634    fn from(s: Box<ByteStr>) -> Box<[u8]> {
635        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
636        unsafe { Box::from_raw(Box::into_raw(s) as _) }
637    }
638}
639
640#[unstable(feature = "bstr", issue = "134915")]
641#[cfg(not(no_rc))]
642impl From<Rc<[u8]>> for Rc<ByteStr> {
643    #[inline]
644    fn from(s: Rc<[u8]>) -> Rc<ByteStr> {
645        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
646        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
647    }
648}
649
650#[unstable(feature = "bstr", issue = "134915")]
651#[cfg(not(no_rc))]
652impl From<Rc<ByteStr>> for Rc<[u8]> {
653    #[inline]
654    fn from(s: Rc<ByteStr>) -> Rc<[u8]> {
655        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
656        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
657    }
658}
659
660#[unstable(feature = "bstr", issue = "134915")]
661#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
662impl From<Arc<[u8]>> for Arc<ByteStr> {
663    #[inline]
664    fn from(s: Arc<[u8]>) -> Arc<ByteStr> {
665        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
666        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
667    }
668}
669
670#[unstable(feature = "bstr", issue = "134915")]
671#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
672impl From<Arc<ByteStr>> for Arc<[u8]> {
673    #[inline]
674    fn from(s: Arc<ByteStr>) -> Arc<[u8]> {
675        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
676        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
677    }
678}
679
680// PartialOrd with `Vec<u8>` omitted to avoid inference failures
681impl_partial_eq!(ByteStr, Vec<u8>);
682// PartialOrd with `String` omitted to avoid inference failures
683impl_partial_eq!(ByteStr, String);
684impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, ByteStr>);
685impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, str>);
686impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, [u8]>);
687
688#[unstable(feature = "bstr", issue = "134915")]
689impl<'a> TryFrom<&'a ByteStr> for String {
690    type Error = core::str::Utf8Error;
691
692    #[inline]
693    fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
694        Ok(core::str::from_utf8(&s.0)?.into())
695    }
696}
697
698impl ByteStr {
699    /// Try to get a `String` representation of the `&ByteStr`, if it is valid
700    /// UTF-8.
701    ///
702    /// This method is named `to_string()` because we want `ByteStr` to
703    /// implement `Display`, but the `ToString` trait has a blanket
704    /// implementation for types that implement `Display`, and the trait version
705    /// will use the Unicode replacement character rather than returning a
706    /// `Result` and allowing for the possibility of the content not being UTF-8.
707    #[unstable(feature = "bstr_to_string", issue = "134915")]
708    #[rustc_allow_incoherent_impl]
709    pub fn to_string(&self) -> Result<String, Utf8Error> {
710        // Avoid allocating a copy of the contents for invalid UTF-8
711        if let Err(e) = str::from_utf8(&self.0) {
712            return Err(e);
713        }
714        // SAFETY: we just checked that the contents are valid UTF-8
715        Ok(unsafe { String::from_utf8_unchecked(self.0.to_vec()) })
716    }
717}