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}