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