1#![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#[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 #[unstable(feature = "bstr_to_string", issue = "134915")]
74 #[rustc_allow_incoherent_impl]
75 pub fn to_string(&self) -> Result<String, Utf8Error> {
76 if let Err(e) = str::from_utf8(&self.0) {
78 return Err(e);
79 }
80 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#[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#[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#[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
530impl_partial_eq!(ByteString, Vec<u8>);
532impl_partial_eq!(ByteString, [u8]);
534impl_partial_eq!(ByteString, &[u8]);
536impl_partial_eq!(ByteString, String);
538impl_partial_eq!(ByteString, str);
540impl_partial_eq!(ByteString, &str);
542impl_partial_eq_ord!(ByteString, ByteStr);
543impl_partial_eq_ord!(ByteString, &ByteStr);
544impl_partial_eq_n!(ByteString, [u8; N]);
546impl_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#[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 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 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 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 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 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 unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
671 }
672}
673
674impl_partial_eq!(ByteStr, Vec<u8>);
676impl_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 #[unstable(feature = "bstr_to_string", issue = "134915")]
702 #[rustc_allow_incoherent_impl]
703 pub fn to_string(&self) -> Result<String, Utf8Error> {
704 if let Err(e) = str::from_utf8(&self.0) {
706 return Err(e);
707 }
708 Ok(unsafe { String::from_utf8_unchecked(self.0.to_vec()) })
710 }
711}