diff --git a/library/alloc/src/bstr.rs b/library/alloc/src/bstr.rs deleted file mode 100644 index f48b2d52e80c1..0000000000000 --- a/library/alloc/src/bstr.rs +++ /dev/null @@ -1,710 +0,0 @@ -//! The `ByteStr` and `ByteString` types and trait implementations. - -// This could be more fine-grained. -#![cfg(not(no_global_oom_handling))] - -use core::borrow::{Borrow, BorrowMut}; -#[unstable(feature = "bstr", issue = "134915")] -pub use core::bstr::ByteStr; -use core::bstr::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord}; -use core::cmp::Ordering; -use core::ops::{ - Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, - RangeTo, RangeToInclusive, -}; -use core::str::{FromStr, Utf8Error}; -use core::{fmt, hash}; - -use crate::borrow::{Cow, ToOwned}; -use crate::boxed::Box; -#[cfg(not(no_rc))] -use crate::rc::Rc; -use crate::string::String; -#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] -use crate::sync::Arc; -use crate::vec::Vec; - -/// A wrapper for `Vec` representing a human-readable string that's conventionally, but not -/// always, UTF-8. -/// -/// Unlike `String`, this type permits non-UTF-8 contents, making it suitable for user input, -/// non-native filenames (as `Path` only supports native filenames), and other applications that -/// need to round-trip whatever data the user provides. -/// -/// A `ByteString` owns its contents and can grow and shrink, like a `Vec` or `String`. For a -/// borrowed byte string, see [`ByteStr`](../../std/bstr/struct.ByteStr.html). -/// -/// `ByteString` implements `Deref` to `&Vec`, so all methods available on `&Vec` are -/// available on `ByteString`. Similarly, `ByteString` implements `DerefMut` to `&mut Vec`, -/// so you can modify a `ByteString` using any method available on `&mut Vec`. -/// -/// The `Debug` and `Display` implementations for `ByteString` are the same as those for `ByteStr`, -/// showing invalid UTF-8 as hex escapes or the Unicode replacement character, respectively. -#[unstable(feature = "bstr", issue = "134915")] -#[repr(transparent)] -#[derive(Clone, Default)] -#[doc(alias = "BString")] -pub struct ByteString(pub Vec); - -impl ByteString { - #[inline] - pub(crate) fn as_bytes(&self) -> &[u8] { - &self.0 - } - - #[inline] - pub(crate) fn as_bytestr(&self) -> &ByteStr { - ByteStr::new(&self.0) - } - - #[inline] - pub(crate) fn as_mut_bytestr(&mut self) -> &mut ByteStr { - ByteStr::from_bytes_mut(&mut self.0) - } - /// Try to get a `String` representation of the `&ByteString`, if it is - /// valid UTF-8. - /// - /// This method is named `to_string()` because we want `ByteString` to - /// implement `Display`, but the `ToString` trait has a blanket - /// implementation for types that implement `Display`, and the trait version - /// will use the Unicode replacement character rather than returning a - /// `Result` and allowing for the possibility of the content not being UTF-8. - #[unstable(feature = "bstr_to_string", issue = "134915")] - #[rustc_allow_incoherent_impl] - pub fn to_string(&self) -> Result { - // Avoid allocating a copy of the contents for invalid UTF-8 - if let Err(e) = str::from_utf8(&self.0) { - return Err(e); - } - // SAFETY: we just checked that the contents are valid UTF-8 - Ok(unsafe { String::from_utf8_unchecked(self.0.clone()) }) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Deref for ByteString { - type Target = Vec; - - #[inline] - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl DerefMut for ByteString { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - -#[unstable(feature = "deref_pure_trait", issue = "87121")] -unsafe impl DerefPure for ByteString {} - -#[unstable(feature = "bstr", issue = "134915")] -impl fmt::Debug for ByteString { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_bytestr(), f) - } -} - -#[unstable(feature = "bstr_to_string", issue = "134915")] -impl fmt::Display for ByteString { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self.as_bytestr(), f) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl AsRef<[u8]> for ByteString { - #[inline] - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl AsRef for ByteString { - #[inline] - fn as_ref(&self) -> &ByteStr { - self.as_bytestr() - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl AsMut<[u8]> for ByteString { - #[inline] - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl AsMut for ByteString { - #[inline] - fn as_mut(&mut self) -> &mut ByteStr { - self.as_mut_bytestr() - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Borrow<[u8]> for ByteString { - #[inline] - fn borrow(&self) -> &[u8] { - &self.0 - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Borrow for ByteString { - #[inline] - fn borrow(&self) -> &ByteStr { - self.as_bytestr() - } -} - -// `impl Borrow for Vec` omitted to avoid inference failures -// `impl Borrow for String` omitted to avoid inference failures - -#[unstable(feature = "bstr", issue = "134915")] -impl BorrowMut<[u8]> for ByteString { - #[inline] - fn borrow_mut(&mut self) -> &mut [u8] { - &mut self.0 - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl BorrowMut for ByteString { - #[inline] - fn borrow_mut(&mut self) -> &mut ByteStr { - self.as_mut_bytestr() - } -} - -// `impl BorrowMut for Vec` omitted to avoid inference failures - -// Omitted due to inference failures -// -// #[unstable(feature = "bstr", issue = "134915")] -// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString { -// #[inline] -// fn from(s: &'a [u8; N]) -> Self { -// ByteString(s.as_slice().to_vec()) -// } -// } -// -// #[unstable(feature = "bstr", issue = "134915")] -// impl From<[u8; N]> for ByteString { -// #[inline] -// fn from(s: [u8; N]) -> Self { -// ByteString(s.as_slice().to_vec()) -// } -// } -// -// #[unstable(feature = "bstr", issue = "134915")] -// impl<'a> From<&'a [u8]> for ByteString { -// #[inline] -// fn from(s: &'a [u8]) -> Self { -// ByteString(s.to_vec()) -// } -// } -// -// #[unstable(feature = "bstr", issue = "134915")] -// impl From> for ByteString { -// #[inline] -// fn from(s: Vec) -> Self { -// ByteString(s) -// } -// } - -#[unstable(feature = "bstr", issue = "134915")] -impl From for Vec { - #[inline] - fn from(s: ByteString) -> Self { - s.0 - } -} - -// Omitted due to inference failures -// -// #[unstable(feature = "bstr", issue = "134915")] -// impl<'a> From<&'a str> for ByteString { -// #[inline] -// fn from(s: &'a str) -> Self { -// ByteString(s.as_bytes().to_vec()) -// } -// } -// -// #[unstable(feature = "bstr", issue = "134915")] -// impl From for ByteString { -// #[inline] -// fn from(s: String) -> Self { -// ByteString(s.into_bytes()) -// } -// } - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> From<&'a ByteStr> for ByteString { - #[inline] - fn from(s: &'a ByteStr) -> Self { - ByteString(s.0.to_vec()) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> From for Cow<'a, ByteStr> { - #[inline] - fn from(s: ByteString) -> Self { - Cow::Owned(s) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> { - #[inline] - fn from(s: &'a ByteString) -> Self { - Cow::Borrowed(s.as_bytestr()) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl FromIterator for ByteString { - #[inline] - fn from_iter>(iter: T) -> Self { - ByteString(iter.into_iter().collect::().into_bytes()) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl FromIterator for ByteString { - #[inline] - fn from_iter>(iter: T) -> Self { - ByteString(iter.into_iter().collect()) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> FromIterator<&'a str> for ByteString { - #[inline] - fn from_iter>(iter: T) -> Self { - ByteString(iter.into_iter().collect::().into_bytes()) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> FromIterator<&'a [u8]> for ByteString { - #[inline] - fn from_iter>(iter: T) -> Self { - let mut buf = Vec::new(); - for b in iter { - buf.extend_from_slice(b); - } - ByteString(buf) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> FromIterator<&'a ByteStr> for ByteString { - #[inline] - fn from_iter>(iter: T) -> Self { - let mut buf = Vec::new(); - for b in iter { - buf.extend_from_slice(&b.0); - } - ByteString(buf) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl FromIterator for ByteString { - #[inline] - fn from_iter>(iter: T) -> Self { - let mut buf = Vec::new(); - for mut b in iter { - buf.append(&mut b.0); - } - ByteString(buf) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl FromStr for ByteString { - type Err = core::convert::Infallible; - - #[inline] - fn from_str(s: &str) -> Result { - Ok(ByteString(s.as_bytes().to_vec())) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Index for ByteString { - type Output = u8; - - #[inline] - fn index(&self, idx: usize) -> &u8 { - &self.0[idx] - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Index for ByteString { - type Output = ByteStr; - - #[inline] - fn index(&self, _: RangeFull) -> &ByteStr { - self.as_bytestr() - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Index> for ByteString { - type Output = ByteStr; - - #[inline] - fn index(&self, r: Range) -> &ByteStr { - ByteStr::from_bytes(&self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Index> for ByteString { - type Output = ByteStr; - - #[inline] - fn index(&self, r: RangeInclusive) -> &ByteStr { - ByteStr::from_bytes(&self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Index> for ByteString { - type Output = ByteStr; - - #[inline] - fn index(&self, r: RangeFrom) -> &ByteStr { - ByteStr::from_bytes(&self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Index> for ByteString { - type Output = ByteStr; - - #[inline] - fn index(&self, r: RangeTo) -> &ByteStr { - ByteStr::from_bytes(&self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Index> for ByteString { - type Output = ByteStr; - - #[inline] - fn index(&self, r: RangeToInclusive) -> &ByteStr { - ByteStr::from_bytes(&self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl IndexMut for ByteString { - #[inline] - fn index_mut(&mut self, idx: usize) -> &mut u8 { - &mut self.0[idx] - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl IndexMut for ByteString { - #[inline] - fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr { - self.as_mut_bytestr() - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl IndexMut> for ByteString { - #[inline] - fn index_mut(&mut self, r: Range) -> &mut ByteStr { - ByteStr::from_bytes_mut(&mut self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl IndexMut> for ByteString { - #[inline] - fn index_mut(&mut self, r: RangeInclusive) -> &mut ByteStr { - ByteStr::from_bytes_mut(&mut self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl IndexMut> for ByteString { - #[inline] - fn index_mut(&mut self, r: RangeFrom) -> &mut ByteStr { - ByteStr::from_bytes_mut(&mut self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl IndexMut> for ByteString { - #[inline] - fn index_mut(&mut self, r: RangeTo) -> &mut ByteStr { - ByteStr::from_bytes_mut(&mut self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl IndexMut> for ByteString { - #[inline] - fn index_mut(&mut self, r: RangeToInclusive) -> &mut ByteStr { - ByteStr::from_bytes_mut(&mut self.0[r]) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl hash::Hash for ByteString { - #[inline] - fn hash(&self, state: &mut H) { - self.0.hash(state); - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl Eq for ByteString {} - -#[unstable(feature = "bstr", issue = "134915")] -impl PartialEq for ByteString { - #[inline] - fn eq(&self, other: &ByteString) -> bool { - self.0 == other.0 - } -} - -macro_rules! impl_partial_eq_ord_cow { - ($lhs:ty, $rhs:ty) => { - #[unstable(feature = "bstr", issue = "134915")] - impl PartialEq<$rhs> for $lhs { - #[inline] - fn eq(&self, other: &$rhs) -> bool { - let other: &[u8] = (&**other).as_ref(); - PartialEq::eq(self.as_bytes(), other) - } - } - - #[unstable(feature = "bstr", issue = "134915")] - impl PartialEq<$lhs> for $rhs { - #[inline] - fn eq(&self, other: &$lhs) -> bool { - let this: &[u8] = (&**self).as_ref(); - PartialEq::eq(this, other.as_bytes()) - } - } - - #[unstable(feature = "bstr", issue = "134915")] - impl PartialOrd<$rhs> for $lhs { - #[inline] - fn partial_cmp(&self, other: &$rhs) -> Option { - let other: &[u8] = (&**other).as_ref(); - PartialOrd::partial_cmp(self.as_bytes(), other) - } - } - - #[unstable(feature = "bstr", issue = "134915")] - impl PartialOrd<$lhs> for $rhs { - #[inline] - fn partial_cmp(&self, other: &$lhs) -> Option { - let this: &[u8] = (&**self).as_ref(); - PartialOrd::partial_cmp(this, other.as_bytes()) - } - } - }; -} - -// PartialOrd with `Vec` omitted to avoid inference failures -impl_partial_eq!(ByteString, Vec); -// PartialOrd with `[u8]` omitted to avoid inference failures -impl_partial_eq!(ByteString, [u8]); -// PartialOrd with `&[u8]` omitted to avoid inference failures -impl_partial_eq!(ByteString, &[u8]); -// PartialOrd with `String` omitted to avoid inference failures -impl_partial_eq!(ByteString, String); -// PartialOrd with `str` omitted to avoid inference failures -impl_partial_eq!(ByteString, str); -// PartialOrd with `&str` omitted to avoid inference failures -impl_partial_eq!(ByteString, &str); -impl_partial_eq_ord!(ByteString, ByteStr); -impl_partial_eq_ord!(ByteString, &ByteStr); -// PartialOrd with `[u8; N]` omitted to avoid inference failures -impl_partial_eq_n!(ByteString, [u8; N]); -// PartialOrd with `&[u8; N]` omitted to avoid inference failures -impl_partial_eq_n!(ByteString, &[u8; N]); -impl_partial_eq_ord_cow!(ByteString, Cow<'_, ByteStr>); -impl_partial_eq_ord_cow!(ByteString, Cow<'_, str>); -impl_partial_eq_ord_cow!(ByteString, Cow<'_, [u8]>); - -#[unstable(feature = "bstr", issue = "134915")] -impl Ord for ByteString { - #[inline] - fn cmp(&self, other: &ByteString) -> Ordering { - Ord::cmp(&self.0, &other.0) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl PartialOrd for ByteString { - #[inline] - fn partial_cmp(&self, other: &ByteString) -> Option { - PartialOrd::partial_cmp(&self.0, &other.0) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl ToOwned for ByteStr { - type Owned = ByteString; - - #[inline] - fn to_owned(&self) -> ByteString { - ByteString(self.0.to_vec()) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl TryFrom for String { - type Error = crate::string::FromUtf8Error; - - #[inline] - fn try_from(s: ByteString) -> Result { - String::from_utf8(s.0) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> TryFrom<&'a ByteString> for &'a str { - type Error = crate::str::Utf8Error; - - #[inline] - fn try_from(s: &'a ByteString) -> Result { - crate::str::from_utf8(s.0.as_slice()) - } -} - -// Additional impls for `ByteStr` that require types from `alloc`: - -#[unstable(feature = "bstr", issue = "134915")] -impl Clone for Box { - #[inline] - fn clone(&self) -> Self { - Self::from(Box::<[u8]>::from(&self.0)) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> { - #[inline] - fn from(s: &'a ByteStr) -> Self { - Cow::Borrowed(s) - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl From> for Box { - #[inline] - fn from(s: Box<[u8]>) -> Box { - // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. - unsafe { Box::from_raw(Box::into_raw(s) as _) } - } -} - -#[unstable(feature = "bstr", issue = "134915")] -impl From> for Box<[u8]> { - #[inline] - fn from(s: Box) -> Box<[u8]> { - // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. - unsafe { Box::from_raw(Box::into_raw(s) as _) } - } -} - -#[unstable(feature = "bstr", issue = "134915")] -#[cfg(not(no_rc))] -impl From> for Rc { - #[inline] - fn from(s: Rc<[u8]>) -> Rc { - // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. - unsafe { Rc::from_raw(Rc::into_raw(s) as _) } - } -} - -#[unstable(feature = "bstr", issue = "134915")] -#[cfg(not(no_rc))] -impl From> for Rc<[u8]> { - #[inline] - fn from(s: Rc) -> Rc<[u8]> { - // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. - unsafe { Rc::from_raw(Rc::into_raw(s) as _) } - } -} - -#[unstable(feature = "bstr", issue = "134915")] -#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] -impl From> for Arc { - #[inline] - fn from(s: Arc<[u8]>) -> Arc { - // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. - unsafe { Arc::from_raw(Arc::into_raw(s) as _) } - } -} - -#[unstable(feature = "bstr", issue = "134915")] -#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] -impl From> for Arc<[u8]> { - #[inline] - fn from(s: Arc) -> Arc<[u8]> { - // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. - unsafe { Arc::from_raw(Arc::into_raw(s) as _) } - } -} - -// PartialOrd with `Vec` omitted to avoid inference failures -impl_partial_eq!(ByteStr, Vec); -// PartialOrd with `String` omitted to avoid inference failures -impl_partial_eq!(ByteStr, String); -impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, ByteStr>); -impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, str>); -impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, [u8]>); - -#[unstable(feature = "bstr", issue = "134915")] -impl<'a> TryFrom<&'a ByteStr> for String { - type Error = core::str::Utf8Error; - - #[inline] - fn try_from(s: &'a ByteStr) -> Result { - Ok(core::str::from_utf8(&s.0)?.into()) - } -} - -impl ByteStr { - /// Try to get a `String` representation of the `&ByteStr`, if it is valid - /// UTF-8. - /// - /// This method is named `to_string()` because we want `ByteStr` to - /// implement `Display`, but the `ToString` trait has a blanket - /// implementation for types that implement `Display`, and the trait version - /// will use the Unicode replacement character rather than returning a - /// `Result` and allowing for the possibility of the content not being UTF-8. - #[unstable(feature = "bstr_to_string", issue = "134915")] - #[rustc_allow_incoherent_impl] - pub fn to_string(&self) -> Result { - // Avoid allocating a copy of the contents for invalid UTF-8 - if let Err(e) = str::from_utf8(&self.0) { - return Err(e); - } - // SAFETY: we just checked that the contents are valid UTF-8 - Ok(unsafe { String::from_utf8_unchecked(self.0.to_vec()) }) - } -} diff --git a/library/alloc/src/byte_str.rs b/library/alloc/src/byte_str.rs new file mode 100644 index 0000000000000..8f70e309c9084 --- /dev/null +++ b/library/alloc/src/byte_str.rs @@ -0,0 +1,1005 @@ +//! The `ByteStr` and `ByteString` types and trait implementations. + +// This could be more fine-grained. +#![cfg(not(no_global_oom_handling))] + +use core::borrow::{Borrow, BorrowMut}; +#[unstable(feature = "byte_str", issue = "134915")] +pub use core::byte_str::ByteStr; +use core::byte_str::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord}; +use core::cmp::Ordering; +use core::ops::{ + Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, + RangeTo, RangeToInclusive, +}; +use core::str::{FromStr, Utf8Error}; +use core::{fmt, hash}; + +use crate::borrow::{Cow, ToOwned}; +use crate::boxed::Box; +use crate::collections::TryReserveError; +#[cfg(not(no_rc))] +use crate::rc::Rc; +use crate::string::String; +#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] +use crate::sync::Arc; +use crate::vec::Vec; + +/// A wrapper for `Vec` representing a human-readable string that's conventionally, but not +/// always, UTF-8. +/// +/// Unlike `String`, this type permits non-UTF-8 contents, making it suitable for user input, +/// non-native filenames (as `Path` only supports native filenames), and other applications that +/// need to round-trip whatever data the user provides. +/// +/// A `ByteString` owns its contents and can grow and shrink, like a `Vec` or `String`. For a +/// borrowed byte string, see [`ByteStr`](../../std/byte_str/struct.ByteStr.html). +/// +/// `ByteString` implements `Deref` to `&Vec`, so all methods available on `&Vec` are +/// available on `ByteString`. Similarly, `ByteString` implements `DerefMut` to `&mut Vec`, +/// so you can modify a `ByteString` using any method available on `&mut Vec`. +/// +/// The `Debug` and `Display` implementations for `ByteString` are the same as those for `ByteStr`, +/// showing invalid UTF-8 as hex escapes or the Unicode replacement character, respectively. +#[unstable(feature = "byte_str", issue = "134915")] +#[repr(transparent)] +#[derive(Clone, Default)] +#[doc(alias = "BString")] +pub struct ByteString(pub(crate) Vec); + +impl ByteString { + /// Creates an empty `ByteString`. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn new() -> ByteString { + ByteString(Vec::new()) + } + + /// Converts to a [`ByteStr`] slice. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let byte_str = ByteStr::new("foo"); + /// let byte_string = byte_str.to_byte_string(); + /// assert_eq!(byte_string.as_byte_str(), byte_str); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn as_byte_str(&self) -> &ByteStr { + ByteStr::new(&self.0) + } + + /// Converts to a mutable [`ByteStr`] slice. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn as_mut_byte_str(&mut self) -> &mut ByteStr { + ByteStr::new_mut(&mut self.0) + } + + /// Returns a reference to the underlying vector for this `ByteString`. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn as_vec(&self) -> &Vec { + &self.0 + } + + /// Returns a mutable reference to the underlying vector for this `ByteString`. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn as_mut_vec(&mut self) -> &mut Vec { + &mut self.0 + } + + /// Converts to a vector of bytes. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn into_bytes(self) -> Vec { + self.0 + } + + /// Converts to a boxed slice of bytes. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn into_boxed_bytes(self) -> Box<[u8]> { + self.into_bytes().into_boxed_slice() + } + + /// Converts to a boxed byte string. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn into_boxed_byte_str(self) -> Box { + self.into_bytes().into_boxed_slice().into_boxed_byte_str() + } + + /// Converts a `ByteString` into a [`String`] if it contains valid Unicode data. + /// + /// On failure, ownership of the original `ByteString` is returned. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn into_string(self) -> Result { + String::from_utf8(self.0).map_err(|e| ByteString(e.into_bytes())) + } + + /// Extends the byte string with the given &[ByteStr] slice. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn push>(&mut self, s: S) { + self.0.extend_from_slice(s.as_ref().as_bytes()) + } + + /// Pushes a single byte onto the byte string. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn push_byte(&mut self, b: u8) { + self.0.push(b) + } + + /// Creates a new [`ByteString`] with at least the given capacity. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn with_capacity(capacity: usize) -> ByteString { + ByteString(Vec::with_capacity(capacity)) + } + + /// Truncates the byte string to zero length. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn clear(&mut self) { + self.0.clear() + } + + /// Returns the number of bytes that can be pushed to this `ByteString` without reallocating. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn capacity(&self) -> usize { + self.0.capacity() + } + + /// Reserves capacity for at least `additional` more capacity to be inserted in the given + /// `ByteString`. Does nothing if the capacity is already sufficient. + /// + /// The collection may reserve more space to speculatively avoid frequent reallocations. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn reserve(&mut self, additional: usize) { + self.0.reserve(additional) + } + + /// Tries to reserve capacity for at least `additional` more bytes + /// in the given `ByteString`. The string may reserve more space to speculatively avoid + /// frequent reallocations. After calling `try_reserve`, capacity will be + /// greater than or equal to `self.len() + additional` if it returns `Ok(())`. + /// Does nothing if capacity is already sufficient. This method preserves + /// the contents even if an error occurs. + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { + self.0.try_reserve(additional) + } + + /// Reserves the minimum capacity for at least `additional` more bytes to + /// be inserted in the given `ByteString`. Does nothing if the capacity is + /// already sufficient. + /// + /// Note that the allocator may give the collection more space than it + /// requests. Therefore, capacity can not be relied upon to be precisely + /// minimal. Prefer [`reserve`] if future insertions are expected. + /// + /// [`reserve`]: ByteString::reserve + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn reserve_exact(&mut self, additional: usize) { + self.0.reserve_exact(additional) + } + + /// Tries to reserve the minimum capacity for at least `additional` + /// more bytes in the given `ByteString`. After calling + /// `try_reserve_exact`, capacity will be greater than or equal to + /// `self.len() + additional` if it returns `Ok(())`. + /// Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the `ByteString` more space than it + /// requests. Therefore, capacity can not be relied upon to be precisely + /// minimal. Prefer [`try_reserve`] if future insertions are expected. + /// + /// [`try_reserve`]: ByteString::try_reserve + /// + /// # Errors + /// + /// If the capacity overflows, or the allocator reports a failure, then an error + /// is returned. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> { + self.0.try_reserve_exact(additional) + } + + /// Shrinks the capacity of the `ByteString` to match its length. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn shrink_to_fit(&mut self) { + self.0.shrink_to_fit() + } + + /// Shrinks the capacity of the [`ByteString`] with a lower bound. + /// + /// The capacity will remain at least as large as both the length and the supplied value. + /// + /// If the current capacity is less than the lower limit, this is a no-op. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.0.shrink_to(min_capacity) + } + + /// Consumes and leaks the `ByteString`, returning a mutable reference to the contents, + /// `&'a mut ByteStr`. + /// + /// The caller has free choice over the returned lifetime, including `’static`. Indeed, this function is ideally used for data that lives for the remainder of the program’s life, as dropping the returned reference will cause a memory leak. + /// + /// It does not reallocate or shrink the `ByteString`, so the leaked allocation may include + /// unused capacity that is not part of the returned slice. If you want discard excess capacity, + /// call [`into_boxed_byte_str`], and then [`Box::leak`] instead. However, keep in mind that + /// trimming the capacity may result in a reallocation and copy. + /// + /// [`into_boxed_byte_str`]: ByteString::into_boxed_byte_str + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn leak<'a>(self) -> &'a mut ByteStr { + ByteStr::new_mut(self.0.leak()) + } + + /// Truncate the [`ByteString`] to the specified length. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn truncate(&mut self, len: usize) { + self.0.truncate(len) + } + /// Try to get a `String` representation of the `&ByteString`, if it is + /// valid UTF-8. + /// + /// This method is named `to_string()` because we want `ByteString` to + /// implement `Display`, but the `ToString` trait has a blanket + /// implementation for types that implement `Display`, and the trait version + /// will use the Unicode replacement character rather than returning a + /// `Result` and allowing for the possibility of the content not being UTF-8. + #[unstable(feature = "byte_str_to_string", issue = "134915")] + #[rustc_allow_incoherent_impl] + pub fn to_string(&self) -> Result { + // Avoid allocating a copy of the contents for invalid UTF-8 + if let Err(e) = str::from_utf8(&self.0) { + return Err(e); + } + // SAFETY: we just checked that the contents are valid UTF-8 + Ok(unsafe { String::from_utf8_unchecked(self.0.clone()) }) + } +} + +impl ByteStr { + /// Converts a `ByteStr` to a [Cow]<[str]>. + /// + /// Any non-UTF-8 sequences are replaced with + /// [U+FFFD REPLACEMENT CHARACTER][char::REPLACEMENT_CHARACTER]. + /// + /// # Examples + /// + /// Calling `to_string_lossy` on a `ByteStr` with invalid unicode: + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let byte_str = ByteStr::new(b"hello, \x80\x80!"); + /// assert_eq!(byte_str.to_string_lossy(), "hello, ��!"); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_allow_incoherent_impl] + pub fn to_string_lossy(&self) -> Cow<'_, str> { + String::from_utf8_lossy(self.as_bytes()) + } + + /// Converts a `ByteStr` to an owned [`ByteString`]. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_allow_incoherent_impl] + pub fn to_byte_string(&self) -> ByteString { + ByteString(self.as_bytes().to_vec()) + } + + /// Returns an owned [`ByteString`] containing a copy of this string where each byte + /// is mapped to its ASCII upper case equivalent. + /// + /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', + /// but non-ASCII letters are unchanged. + /// + /// To uppercase the value in-place, use [`make_ascii_uppercase`]. + /// + /// [`make_ascii_uppercase`]: ByteStr::make_ascii_uppercase + #[unstable(feature = "byte_str", issue = "134915")] + #[must_use = "this returns the uppercase bytes as a new ByteString, \ + without modifying the original"] + #[inline] + #[rustc_allow_incoherent_impl] + pub fn to_ascii_uppercase(&self) -> ByteString { + let mut me = self.to_byte_string(); + me.make_ascii_uppercase(); + me + } + + /// Returns an owned [`ByteString`] containing a copy of this string where each byte + /// is mapped to its ASCII lower case equivalent. + /// + /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', + /// but non-ASCII letters are unchanged. + /// + /// To lowercase the value in-place, use [`make_ascii_lowercase`]. + /// + /// [`make_ascii_lowercase`]: ByteStr::make_ascii_lowercase + #[unstable(feature = "byte_str", issue = "134915")] + #[must_use = "this returns the uppercase bytes as a new ByteString, \ + without modifying the original"] + #[inline] + #[rustc_allow_incoherent_impl] + pub fn to_ascii_lowercase(&self) -> ByteString { + let mut me = self.to_byte_string(); + me.make_ascii_lowercase(); + me + } + + /// Converts a [Box]<[ByteStr]> into a [Box]<\[u8\]> without + /// copying or allocating. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_allow_incoherent_impl] + pub fn into_boxed_bytes(self: Box) -> Box<[u8]> { + // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. + unsafe { Box::from_raw(Box::into_raw(self) as _) } + } + + /// Converts a [Box]<[ByteStr]> to an owned [`ByteString`]. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_allow_incoherent_impl] + pub fn into_byte_string(self: Box) -> ByteString { + ByteString(self.into_boxed_bytes().into_vec()) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Deref for ByteString { + type Target = ByteStr; + + #[inline] + fn deref(&self) -> &Self::Target { + self.as_byte_str() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl DerefMut for ByteString { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_byte_str() + } +} + +#[unstable(feature = "deref_pure_trait", issue = "87121")] +unsafe impl DerefPure for ByteString {} + +#[unstable(feature = "byte_str", issue = "134915")] +impl fmt::Debug for ByteString { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(self.as_byte_str(), f) + } +} + +#[unstable(feature = "byte_str_to_string", issue = "134915")] +impl fmt::Display for ByteString { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self.as_byte_str(), f) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl AsRef<[u8]> for ByteString { + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl AsRef for ByteString { + #[inline] + fn as_ref(&self) -> &ByteStr { + self.as_byte_str() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl AsMut<[u8]> for ByteString { + #[inline] + fn as_mut(&mut self) -> &mut [u8] { + self.as_bytes_mut() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl AsMut for ByteString { + #[inline] + fn as_mut(&mut self) -> &mut ByteStr { + self.as_mut_byte_str() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Borrow<[u8]> for ByteString { + #[inline] + fn borrow(&self) -> &[u8] { + self.as_bytes() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Borrow for ByteString { + #[inline] + fn borrow(&self) -> &ByteStr { + self.as_byte_str() + } +} + +// `impl Borrow for Vec` omitted to avoid inference failures +// `impl Borrow for String` omitted to avoid inference failures + +#[unstable(feature = "byte_str", issue = "134915")] +impl BorrowMut<[u8]> for ByteString { + #[inline] + fn borrow_mut(&mut self) -> &mut [u8] { + self.as_bytes_mut() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl BorrowMut for ByteString { + #[inline] + fn borrow_mut(&mut self) -> &mut ByteStr { + self.as_mut_byte_str() + } +} + +// `impl BorrowMut for Vec` omitted to avoid inference failures + +// Omitted due to inference failures +// +// #[unstable(feature = "byte_str", issue = "134915")] +// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString { +// #[inline] +// fn from(s: &'a [u8; N]) -> Self { +// ByteString(s.as_slice().to_vec()) +// } +// } +// +// #[unstable(feature = "byte_str", issue = "134915")] +// impl From<[u8; N]> for ByteString { +// #[inline] +// fn from(s: [u8; N]) -> Self { +// ByteString(s.as_slice().to_vec()) +// } +// } +// +// #[unstable(feature = "byte_str", issue = "134915")] +// impl<'a> From<&'a [u8]> for ByteString { +// #[inline] +// fn from(s: &'a [u8]) -> Self { +// ByteString(s.to_vec()) +// } +// } +// +// #[unstable(feature = "byte_str", issue = "134915")] +// impl From> for ByteString { +// #[inline] +// fn from(s: Vec) -> Self { +// ByteString(s) +// } +// } + +#[unstable(feature = "byte_str", issue = "134915")] +impl From for Vec { + #[inline] + fn from(s: ByteString) -> Self { + s.0 + } +} + +// Omitted due to inference failures +// +// #[unstable(feature = "byte_str", issue = "134915")] +// impl<'a> From<&'a str> for ByteString { +// #[inline] +// fn from(s: &'a str) -> Self { +// ByteString(s.as_bytes().to_vec()) +// } +// } +// +// #[unstable(feature = "byte_str", issue = "134915")] +// impl From for ByteString { +// #[inline] +// fn from(s: String) -> Self { +// ByteString(s.into_bytes()) +// } +// } + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> From<&'a ByteStr> for ByteString { + #[inline] + fn from(s: &'a ByteStr) -> Self { + s.to_byte_string() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> From for Cow<'a, ByteStr> { + #[inline] + fn from(s: ByteString) -> Self { + Cow::Owned(s) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> { + #[inline] + fn from(s: &'a ByteString) -> Self { + Cow::Borrowed(s.as_byte_str()) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl FromIterator for ByteString { + #[inline] + fn from_iter>(iter: T) -> Self { + ByteString(iter.into_iter().collect::().into_bytes()) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl FromIterator for ByteString { + #[inline] + fn from_iter>(iter: T) -> Self { + ByteString(iter.into_iter().collect()) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> FromIterator<&'a str> for ByteString { + #[inline] + fn from_iter>(iter: T) -> Self { + ByteString(iter.into_iter().collect::().into_bytes()) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> FromIterator<&'a [u8]> for ByteString { + #[inline] + fn from_iter>(iter: T) -> Self { + let mut buf = ByteString::new(); + for b in iter { + buf.push(ByteStr::new(b)); + } + buf + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> FromIterator<&'a ByteStr> for ByteString { + #[inline] + fn from_iter>(iter: T) -> Self { + let mut buf = ByteString::new(); + for b in iter { + buf.push(b); + } + buf + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl FromIterator for ByteString { + #[inline] + fn from_iter>(iter: T) -> Self { + let mut buf = Vec::new(); + for mut b in iter { + buf.append(&mut b.0); + } + ByteString(buf) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl FromStr for ByteString { + type Err = core::convert::Infallible; + + #[inline] + fn from_str(s: &str) -> Result { + Ok(ByteString(s.as_bytes().to_vec())) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Index for ByteString { + type Output = u8; + + #[inline] + fn index(&self, idx: usize) -> &u8 { + &self.0[idx] + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Index for ByteString { + type Output = ByteStr; + + #[inline] + fn index(&self, _: RangeFull) -> &ByteStr { + self.as_byte_str() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Index> for ByteString { + type Output = ByteStr; + + #[inline] + fn index(&self, r: Range) -> &ByteStr { + ByteStr::new(&self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Index> for ByteString { + type Output = ByteStr; + + #[inline] + fn index(&self, r: RangeInclusive) -> &ByteStr { + ByteStr::new(&self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Index> for ByteString { + type Output = ByteStr; + + #[inline] + fn index(&self, r: RangeFrom) -> &ByteStr { + ByteStr::new(&self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Index> for ByteString { + type Output = ByteStr; + + #[inline] + fn index(&self, r: RangeTo) -> &ByteStr { + ByteStr::new(&self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Index> for ByteString { + type Output = ByteStr; + + #[inline] + fn index(&self, r: RangeToInclusive) -> &ByteStr { + ByteStr::new(&self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl IndexMut for ByteString { + #[inline] + fn index_mut(&mut self, idx: usize) -> &mut u8 { + &mut self.0[idx] + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl IndexMut for ByteString { + #[inline] + fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr { + self.as_mut_byte_str() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl IndexMut> for ByteString { + #[inline] + fn index_mut(&mut self, r: Range) -> &mut ByteStr { + ByteStr::new_mut(&mut self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl IndexMut> for ByteString { + #[inline] + fn index_mut(&mut self, r: RangeInclusive) -> &mut ByteStr { + ByteStr::new_mut(&mut self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl IndexMut> for ByteString { + #[inline] + fn index_mut(&mut self, r: RangeFrom) -> &mut ByteStr { + ByteStr::new_mut(&mut self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl IndexMut> for ByteString { + #[inline] + fn index_mut(&mut self, r: RangeTo) -> &mut ByteStr { + ByteStr::new_mut(&mut self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl IndexMut> for ByteString { + #[inline] + fn index_mut(&mut self, r: RangeToInclusive) -> &mut ByteStr { + ByteStr::new_mut(&mut self.0[r]) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl hash::Hash for ByteString { + #[inline] + fn hash(&self, state: &mut H) { + self.0.hash(state); + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl Eq for ByteString {} + +#[unstable(feature = "byte_str", issue = "134915")] +impl PartialEq for ByteString { + #[inline] + fn eq(&self, other: &ByteString) -> bool { + self.0 == other.0 + } +} + +macro_rules! impl_partial_eq_ord_cow { + ($lhs:ty, $rhs:ty) => { + #[unstable(feature = "byte_str", issue = "134915")] + impl PartialEq<$rhs> for $lhs { + #[inline] + fn eq(&self, other: &$rhs) -> bool { + let other: &[u8] = (&**other).as_ref(); + PartialEq::eq(self.as_bytes(), other) + } + } + + #[unstable(feature = "byte_str", issue = "134915")] + impl PartialEq<$lhs> for $rhs { + #[inline] + fn eq(&self, other: &$lhs) -> bool { + let this: &[u8] = (&**self).as_ref(); + PartialEq::eq(this, other.as_bytes()) + } + } + + #[unstable(feature = "byte_str", issue = "134915")] + impl PartialOrd<$rhs> for $lhs { + #[inline] + fn partial_cmp(&self, other: &$rhs) -> Option { + let other: &[u8] = (&**other).as_ref(); + PartialOrd::partial_cmp(self.as_bytes(), other) + } + } + + #[unstable(feature = "byte_str", issue = "134915")] + impl PartialOrd<$lhs> for $rhs { + #[inline] + fn partial_cmp(&self, other: &$lhs) -> Option { + let this: &[u8] = (&**self).as_ref(); + PartialOrd::partial_cmp(this, other.as_bytes()) + } + } + }; +} + +// PartialOrd with `Vec` omitted to avoid inference failures +impl_partial_eq!(ByteString, Vec); +// PartialOrd with `[u8]` omitted to avoid inference failures +impl_partial_eq!(ByteString, [u8]); +// PartialOrd with `&[u8]` omitted to avoid inference failures +impl_partial_eq!(ByteString, &[u8]); +// PartialOrd with `String` omitted to avoid inference failures +impl_partial_eq!(ByteString, String); +// PartialOrd with `str` omitted to avoid inference failures +impl_partial_eq!(ByteString, str); +// PartialOrd with `&str` omitted to avoid inference failures +impl_partial_eq!(ByteString, &str); +impl_partial_eq_ord!(ByteString, ByteStr); +impl_partial_eq_ord!(ByteString, &ByteStr); +// PartialOrd with `[u8; N]` omitted to avoid inference failures +impl_partial_eq_n!(ByteString, [u8; N]); +// PartialOrd with `&[u8; N]` omitted to avoid inference failures +impl_partial_eq_n!(ByteString, &[u8; N]); +impl_partial_eq_ord_cow!(ByteString, Cow<'_, ByteStr>); +impl_partial_eq_ord_cow!(ByteString, Cow<'_, str>); +impl_partial_eq_ord_cow!(ByteString, Cow<'_, [u8]>); + +#[unstable(feature = "byte_str", issue = "134915")] +impl Ord for ByteString { + #[inline] + fn cmp(&self, other: &ByteString) -> Ordering { + Ord::cmp(&self.0, &other.0) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl PartialOrd for ByteString { + #[inline] + fn partial_cmp(&self, other: &ByteString) -> Option { + PartialOrd::partial_cmp(&self.0, &other.0) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl ToOwned for ByteStr { + type Owned = ByteString; + + #[inline] + fn to_owned(&self) -> ByteString { + self.to_byte_string() + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl TryFrom for String { + type Error = crate::string::FromUtf8Error; + + #[inline] + fn try_from(s: ByteString) -> Result { + String::from_utf8(s.0) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> TryFrom<&'a ByteString> for &'a str { + type Error = crate::str::Utf8Error; + + #[inline] + fn try_from(s: &'a ByteString) -> Result { + crate::str::from_utf8(s.0.as_slice()) + } +} + +// Additional impls for `ByteStr` that require types from `alloc`: + +#[unstable(feature = "byte_str", issue = "134915")] +impl Clone for Box { + #[inline] + fn clone(&self) -> Self { + Self::from(Box::<[u8]>::from(self.as_bytes())) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> { + #[inline] + fn from(s: &'a ByteStr) -> Self { + Cow::Borrowed(s) + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl From> for Box { + #[inline] + fn from(s: Box<[u8]>) -> Box { + // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. + unsafe { Box::from_raw(Box::into_raw(s) as _) } + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +impl From> for Box<[u8]> { + #[inline] + fn from(s: Box) -> Box<[u8]> { + // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. + unsafe { Box::from_raw(Box::into_raw(s) as _) } + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +#[cfg(not(no_rc))] +impl From> for Rc { + #[inline] + fn from(s: Rc<[u8]>) -> Rc { + // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. + unsafe { Rc::from_raw(Rc::into_raw(s) as _) } + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +#[cfg(not(no_rc))] +impl From> for Rc<[u8]> { + #[inline] + fn from(s: Rc) -> Rc<[u8]> { + // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. + unsafe { Rc::from_raw(Rc::into_raw(s) as _) } + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] +impl From> for Arc { + #[inline] + fn from(s: Arc<[u8]>) -> Arc { + // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. + unsafe { Arc::from_raw(Arc::into_raw(s) as _) } + } +} + +#[unstable(feature = "byte_str", issue = "134915")] +#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] +impl From> for Arc<[u8]> { + #[inline] + fn from(s: Arc) -> Arc<[u8]> { + // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`. + unsafe { Arc::from_raw(Arc::into_raw(s) as _) } + } +} + +// PartialOrd with `Vec` omitted to avoid inference failures +impl_partial_eq!(ByteStr, Vec); +// PartialOrd with `String` omitted to avoid inference failures +impl_partial_eq!(ByteStr, String); +impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, ByteStr>); +impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, str>); +impl_partial_eq_ord_cow!(&ByteStr, Cow<'_, [u8]>); + +#[unstable(feature = "byte_str", issue = "134915")] +impl<'a> TryFrom<&'a ByteStr> for String { + type Error = core::str::Utf8Error; + + #[inline] + fn try_from(s: &'a ByteStr) -> Result { + Ok(core::str::from_utf8(s.as_bytes())?.into()) + } +} + +impl ByteStr { + /// Try to get a `String` representation of the `&ByteStr`, if it is valid + /// UTF-8. + /// + /// This method is named `to_string()` because we want `ByteStr` to + /// implement `Display`, but the `ToString` trait has a blanket + /// implementation for types that implement `Display`, and the trait version + /// will use the Unicode replacement character rather than returning a + /// `Result` and allowing for the possibility of the content not being UTF-8. + #[unstable(feature = "byte_str_to_string", issue = "134915")] + #[rustc_allow_incoherent_impl] + pub fn to_string(&self) -> Result { + // Avoid allocating a copy of the contents for invalid UTF-8 + if let Err(e) = str::from_utf8(self.as_bytes()) { + return Err(e); + } + // SAFETY: we just checked that the contents are valid UTF-8 + Ok(unsafe { String::from_utf8_unchecked(self.to_vec()) }) + } +} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 89b15a169dce0..e2847809269ce 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -96,8 +96,8 @@ #![feature(async_fn_traits)] #![feature(async_iterator)] #![feature(borrowed_buf_init)] -#![feature(bstr)] -#![feature(bstr_internals)] +#![feature(byte_str)] +#![feature(byte_str_internals)] #![feature(can_vector)] #![feature(case_ignorable)] #![feature(cast_maybe_uninit)] @@ -246,8 +246,8 @@ pub mod alloc; // to allow code to have `use boxed::Box;` declarations. pub mod borrow; pub mod boxed; -#[unstable(feature = "bstr", issue = "134915")] -pub mod bstr; +#[unstable(feature = "byte_str", issue = "134915")] +pub mod byte_str; pub mod collections; #[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))] pub mod ffi; diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index e6b540f093ba5..7ae2a8d41fb7b 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -11,6 +11,8 @@ use core::borrow::{Borrow, BorrowMut}; #[cfg(not(no_global_oom_handling))] +use core::byte_str::ByteStr; +#[cfg(not(no_global_oom_handling))] use core::clone::TrivialClone; #[cfg(not(no_global_oom_handling))] use core::cmp::Ordering::{self, Less}; @@ -660,6 +662,16 @@ impl [u8] { pub fn to_ascii_lowercase(&self) -> Vec { self.iter().map(|b| b.to_ascii_lowercase()).collect() } + + /// Converts a `Box<[u8]>` into a `Box` without copying or allocating. + #[cfg(not(no_global_oom_handling))] + #[rustc_allow_incoherent_impl] + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + pub fn into_boxed_byte_str(self: Box<[u8]>) -> Box { + // SAFETY: `ByteStr` is a thin wrapper over `[u8]` + unsafe { Box::from_raw(Box::into_raw(self) as _) } + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index bd15ec798460f..7ae983ae97834 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -91,6 +91,8 @@ pub use self::extract_if::ExtractIf; use crate::alloc::{Allocator, Global}; use crate::borrow::{Cow, ToOwned}; use crate::boxed::Box; +#[cfg(not(no_global_oom_handling))] +use crate::byte_str::ByteString; use crate::collections::TryReserveError; use crate::raw_vec::RawVec; @@ -3663,6 +3665,17 @@ impl Vec { } } +impl Vec { + /// Converts a vector of bytes into a byte string. + #[cfg(not(no_global_oom_handling))] + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn into_byte_string(self) -> ByteString { + ByteString(self) + } +} + impl Vec<[T; N], A> { /// Takes a `Vec<[T; N]>` and flattens it into a `Vec`. /// diff --git a/library/alloctests/tests/bstr.rs b/library/alloctests/tests/byte_str.rs similarity index 90% rename from library/alloctests/tests/bstr.rs rename to library/alloctests/tests/byte_str.rs index 64a1b901f1300..47738d8cbaba1 100644 --- a/library/alloctests/tests/bstr.rs +++ b/library/alloctests/tests/byte_str.rs @@ -1,11 +1,11 @@ -use alloc::bstr::ByteString; +use alloc::byte_str::ByteStr; use core::assert_matches; #[test] fn test_debug() { - let b1 = ByteString( - b"\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x11\x12\r\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f \x7f\x80\x81\xfe\xff".to_vec() - ); + let b1 = ByteStr::new( + b"\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x11\x12\r\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f \x7f\x80\x81\xfe\xff" + ).to_byte_string(); assert_eq!( r#""\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x11\x12\r\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f \x7f\x80\x81\xfe\xff""#, format!("{:?}", b1), @@ -14,8 +14,8 @@ fn test_debug() { #[test] fn test_display() { - let b1 = ByteString(b"abc".to_vec()); - let b2 = ByteString(b"\xf0\x28\x8c\xbc".to_vec()); + let b1 = ByteStr::new(b"abc").to_byte_string(); + let b2 = ByteStr::new(b"\xf0\x28\x8c\xbc").to_byte_string(); assert_eq!(&format!("{b1}"), "abc"); assert_eq!(&format!("{b2}"), "�(��"); @@ -72,8 +72,8 @@ fn test_display() { #[test] fn test_to_string() { - let b1 = ByteString(b"abc".to_vec()); - let b2 = ByteString(b"\xf0\x28\x8c\xbc".to_vec()); + let b1 = ByteStr::new(b"abc").to_byte_string(); + let b2 = ByteStr::new(b"\xf0\x28\x8c\xbc").to_byte_string(); assert_eq!(Ok("abc".to_string()), b1.to_string()); assert_matches!(b2.to_string(), Err(core::str::Utf8Error { .. })); diff --git a/library/alloctests/tests/lib.rs b/library/alloctests/tests/lib.rs index b2a3e8f8f8e2a..beb33b512764c 100644 --- a/library/alloctests/tests/lib.rs +++ b/library/alloctests/tests/lib.rs @@ -8,9 +8,9 @@ #![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_pop_if)] #![feature(borrowed_buf_init)] -#![feature(bstr)] -#![feature(bstr_to_string)] #![feature(buf_read_has_data_left)] +#![feature(byte_str)] +#![feature(byte_str_to_string)] #![feature(can_vector)] #![feature(casefold)] #![feature(const_btree_len)] @@ -73,8 +73,8 @@ mod arc; mod autotraits; mod borrow; mod boxed; -mod bstr; mod btree_set_hash; +mod byte_str; mod c_str; mod c_str2; mod collections; diff --git a/library/core/src/bstr/mod.rs b/library/core/src/byte_str/mod.rs similarity index 55% rename from library/core/src/bstr/mod.rs rename to library/core/src/byte_str/mod.rs index 0530ddc292a99..ba5be3fc4f420 100644 --- a/library/core/src/bstr/mod.rs +++ b/library/core/src/byte_str/mod.rs @@ -2,12 +2,14 @@ mod traits; -#[unstable(feature = "bstr_internals", issue = "none")] +#[unstable(feature = "byte_str_internals", issue = "none")] pub use traits::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord}; use crate::borrow::{Borrow, BorrowMut}; use crate::fmt::{self, Alignment}; +use crate::marker::Destruct; use crate::ops::{Deref, DerefMut, DerefPure}; +use crate::str; /// A wrapper for `&[u8]` representing a human-readable string that's conventionally, but not /// always, UTF-8. @@ -17,7 +19,7 @@ use crate::ops::{Deref, DerefMut, DerefPure}; /// need to round-trip whatever data the user provides. /// /// For an owned, growable byte string buffer, use -/// [`ByteString`](../../std/bstr/struct.ByteString.html). +/// [`ByteString`](../../std/byte_str/struct.ByteString.html). /// /// `ByteStr` implements `Deref` to `[u8]`, so all methods available on `[u8]` are available on /// `ByteStr`. @@ -37,11 +39,11 @@ use crate::ops::{Deref, DerefMut, DerefPure}; /// /// The `Display` implementation behaves as if the `ByteStr` were first lossily converted to a /// `str`, with invalid UTF-8 presented as the Unicode replacement character (�). -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_has_incoherent_inherent_impls] #[repr(transparent)] #[doc(alias = "BStr")] -pub struct ByteStr(pub [u8]); +pub struct ByteStr(pub(crate) [u8]); impl ByteStr { /// Creates a `ByteStr` slice from anything that can be converted to a byte slice. @@ -53,8 +55,8 @@ impl ByteStr { /// You can create a `ByteStr` from a byte array, a byte slice or a string slice: /// /// ``` - /// # #![feature(bstr)] - /// # use std::bstr::ByteStr; + /// # #![feature(byte_str)] + /// # use std::byte_str::ByteStr; /// let a = ByteStr::new(b"abc"); /// let b = ByteStr::new(&b"abc"[..]); /// let c = ByteStr::new("abc"); @@ -63,12 +65,42 @@ impl ByteStr { /// assert_eq!(a, c); /// ``` #[inline] - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] pub const fn new>(bytes: &B) -> &Self { ByteStr::from_bytes(bytes.as_ref()) } + /// Creates a mutable `ByteStr` slice from anything that can be converted to a mutable byte slice. + /// + /// This is a zero-cost conversion. + /// + /// # Example + /// + /// Unlike `str`, the raw bytes of a `ByteStr` can be safely mutated at any time, since the + /// result is not guaranteed to be valid UTF-8. + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let mut buf = "😀".to_string().into_bytes().into_byte_string(); + /// assert_eq!(format!("{buf}"), "😀"); + /// + /// let s = ByteStr::new_mut(&mut buf); + /// s.as_bytes_mut().reverse(); + /// s[1] = b':'; + /// s[2] = b'('; + /// + /// assert_eq!(format!("{buf}"), "�:(�"); + /// ``` + #[inline] + #[unstable(feature = "byte_str", issue = "134915")] + #[rustc_const_unstable(feature = "const_convert", issue = "143773")] + pub const fn new_mut>(bytes: &mut B) -> &mut Self { + ByteStr::from_bytes_mut(bytes.as_mut()) + } + /// Returns the same string as `&ByteStr`. /// /// This method is redundant when used directly on `&ByteStr`, but @@ -76,7 +108,7 @@ impl ByteStr { /// for example `Box` or `Arc`. #[inline] // #[unstable(feature = "str_as_str", issue = "130366")] - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] pub const fn as_byte_str(&self) -> &ByteStr { self } @@ -88,49 +120,244 @@ impl ByteStr { /// for example `Box` or `MutexGuard`. #[inline] // #[unstable(feature = "str_as_str", issue = "130366")] - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] pub const fn as_mut_byte_str(&mut self) -> &mut ByteStr { self } - #[doc(hidden)] - #[unstable(feature = "bstr_internals", issue = "none")] #[inline] - #[rustc_const_unstable(feature = "bstr_internals", issue = "none")] - pub const fn from_bytes(slice: &[u8]) -> &Self { + pub(crate) const fn from_bytes(slice: &[u8]) -> &Self { // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`, so we can turn a reference to // the wrapped type into a reference to the wrapper type. unsafe { &*(slice as *const [u8] as *const Self) } } - #[doc(hidden)] - #[unstable(feature = "bstr_internals", issue = "none")] #[inline] - #[rustc_const_unstable(feature = "bstr_internals", issue = "none")] - pub const fn from_bytes_mut(slice: &mut [u8]) -> &mut Self { + pub(crate) const fn from_bytes_mut(slice: &mut [u8]) -> &mut Self { // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`, so we can turn a reference to // the wrapped type into a reference to the wrapper type. unsafe { &mut *(slice as *mut [u8] as *mut Self) } } - #[doc(hidden)] - #[unstable(feature = "bstr_internals", issue = "none")] + /// Converts a `ByteStr` slice to a byte slice. To convert the byte slice back into a byte string + /// slice, use [`ByteStr::new`]. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let s = ByteStr::new("bors"); + /// let bytes = s.as_bytes(); + /// assert_eq!(b"bors", bytes); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] #[inline] - #[rustc_const_unstable(feature = "bstr_internals", issue = "none")] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] pub const fn as_bytes(&self) -> &[u8] { &self.0 } - #[doc(hidden)] - #[unstable(feature = "bstr_internals", issue = "none")] + /// Converts a mutable `ByteStr` slice to a mutable byte slice. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let mut s = ByteStr::new("Hello").to_byte_string(); + /// let bytes = s.as_bytes_mut(); + /// assert_eq!(b"Hello", bytes); + /// ``` + /// + /// Mutability: + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let mut s = ByteStr::new("🗻∈🌏").to_byte_string(); + /// let bytes = s.as_bytes_mut(); + /// + /// bytes[0] = 0xF0; + /// bytes[1] = 0x9F; + /// bytes[2] = 0x8D; + /// bytes[3] = 0x94; + /// + /// assert_eq!("🍔∈🌏", s); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] #[inline] - #[rustc_const_unstable(feature = "bstr_internals", issue = "none")] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] pub const fn as_bytes_mut(&mut self) -> &mut [u8] { &mut self.0 } + + /// Yields a &[prim@str] slice if the `ByteStr` is valid unicode. + /// + /// This conversion may entail a check for UTF-8 validity. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let byte_str = ByteStr::new("foo"); + /// assert_eq!(byte_str.to_str(), Some("foo")); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn to_str(&self) -> Option<&str> { + str::from_utf8(&self.0).ok() + } + + /// Checks whether the `ByteStr` is empty. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let byte_str = ByteStr::new(""); + /// assert!(byte_str.is_empty()); + /// + /// let byte_str = ByteStr::new("foo"); + /// assert!(!byte_str.is_empty()); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Returns the length of this `ByteStr` in bytes. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let byte_str = ByteStr::new(""); + /// assert_eq!(byte_str.len(), 0); + /// + /// let byte_str = ByteStr::new("foo"); + /// assert_eq!(byte_str.len(), 3); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn len(&self) -> usize { + self.0.len() + } + + /// Checks if all bytes in this byte string are within the ASCII range. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let ascii = ByteStr::new("hello!\n"); + /// let non_ascii = ByteStr::new("Grüße, Jürgen ❤"); + /// + /// assert!(ascii.is_ascii()); + /// assert!(!non_ascii.is_ascii()); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn is_ascii(&self) -> bool { + self.0.is_ascii() + } + + /// Converts this byte string to its ASCII lower case equivalent in-place. + /// + /// ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, but non-ASCII letters are unchanged. + /// To return a new lowercased value without modifying the existing one, use + /// `ByteStr::to_ascii_lowercase`. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let mut s = ByteStr::new("GRÜßE, JÜRGEN ❤").to_byte_string(); + /// + /// s.make_ascii_lowercase(); + /// + /// assert_eq!("grÜße, jÜrgen ❤", s); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn make_ascii_lowercase(&mut self) { + self.0.make_ascii_lowercase() + } + + /// Converts this byte string to its ASCII upper case equivalent in-place. + /// + /// ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, but non-ASCII letters are unchanged. + /// To return a new uppercased value without modifying the existing one, use + /// `ByteStr::to_ascii_uppercase`. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// let mut s = ByteStr::new("Grüße, Jürgen ❤").to_byte_string(); + /// + /// s.make_ascii_uppercase(); + /// + /// assert_eq!("GRüßE, JüRGEN ❤", s); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn make_ascii_uppercase(&mut self) { + self.0.make_ascii_uppercase() + } + + /// Checks if two byte strings are an ASCII case-insensitive match. + /// + /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, but without allocating and copying + /// temporaries. + /// + /// # Examples + /// + /// ``` + /// #![feature(byte_str)] + /// use std::byte_str::ByteStr; + /// + /// assert!(ByteStr::new("Ferris").eq_ignore_ascii_case("FERRIS")); + /// assert!(ByteStr::new("Ferrös").eq_ignore_ascii_case("FERRöS")); + /// assert!(!ByteStr::new("Ferrös").eq_ignore_ascii_case("FERRÖS")); + /// ``` + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn eq_ignore_ascii_case + [const] Destruct>( + &self, + other: S, + ) -> bool { + let other: &ByteStr = other.as_ref(); + self.0.eq_ignore_ascii_case(&other.0) + } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl Deref for ByteStr { type Target = [u8]; @@ -141,7 +368,7 @@ const impl Deref for ByteStr { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl DerefMut for ByteStr { #[inline] @@ -153,11 +380,11 @@ const impl DerefMut for ByteStr { #[unstable(feature = "deref_pure_trait", issue = "87121")] unsafe impl DerefPure for ByteStr {} -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl fmt::Debug for ByteStr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "\"")?; - for chunk in self.utf8_chunks() { + for chunk in self.0.utf8_chunks() { for c in chunk.valid().chars() { match c { '\0' => write!(f, "\\0")?, @@ -172,11 +399,11 @@ impl fmt::Debug for ByteStr { } } -#[unstable(feature = "bstr_to_string", issue = "134915")] +#[unstable(feature = "byte_str_to_string", issue = "134915")] impl fmt::Display for ByteStr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn emit(byte_str: &ByteStr, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for chunk in byte_str.utf8_chunks() { + for chunk in byte_str.0.utf8_chunks() { f.write_str(chunk.valid())?; if !chunk.invalid().is_empty() { f.write_str("\u{FFFD}")?; @@ -257,7 +484,7 @@ impl fmt::Display for ByteStr { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl AsRef<[u8]> for ByteStr { #[inline] @@ -266,7 +493,7 @@ const impl AsRef<[u8]> for ByteStr { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl AsRef for ByteStr { #[inline] @@ -277,7 +504,7 @@ const impl AsRef for ByteStr { // `impl AsRef for [u8]` omitted to avoid widespread inference failures -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl AsRef for str { #[inline] @@ -286,7 +513,7 @@ const impl AsRef for str { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl AsMut<[u8]> for ByteStr { #[inline] @@ -301,7 +528,7 @@ const impl AsMut<[u8]> for ByteStr { // `impl Borrow for str` omitted to avoid widespread inference failures -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl Borrow<[u8]> for ByteStr { #[inline] @@ -312,7 +539,7 @@ const impl Borrow<[u8]> for ByteStr { // `impl BorrowMut for [u8]` omitted to avoid widespread inference failures -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl BorrowMut<[u8]> for ByteStr { #[inline] @@ -321,14 +548,14 @@ const impl BorrowMut<[u8]> for ByteStr { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl<'a> Default for &'a ByteStr { fn default() -> Self { ByteStr::from_bytes(b"") } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl<'a> Default for &'a mut ByteStr { fn default() -> Self { ByteStr::from_bytes_mut(&mut []) @@ -337,7 +564,7 @@ impl<'a> Default for &'a mut ByteStr { // Omitted due to inference failures // -// #[unstable(feature = "bstr", issue = "134915")] +// #[unstable(feature = "byte_str", issue = "134915")] // impl<'a, const N: usize> From<&'a [u8; N]> for &'a ByteStr { // #[inline] // fn from(s: &'a [u8; N]) -> Self { @@ -345,7 +572,7 @@ impl<'a> Default for &'a mut ByteStr { // } // } // -// #[unstable(feature = "bstr", issue = "134915")] +// #[unstable(feature = "byte_str", issue = "134915")] // impl<'a> From<&'a [u8]> for &'a ByteStr { // #[inline] // fn from(s: &'a [u8]) -> Self { @@ -355,7 +582,7 @@ impl<'a> Default for &'a mut ByteStr { // Omitted due to slice-from-array-issue-113238: // -// #[unstable(feature = "bstr", issue = "134915")] +// #[unstable(feature = "byte_str", issue = "134915")] // impl<'a> From<&'a ByteStr> for &'a [u8] { // #[inline] // fn from(s: &'a ByteStr) -> Self { @@ -363,7 +590,7 @@ impl<'a> Default for &'a mut ByteStr { // } // } // -// #[unstable(feature = "bstr", issue = "134915")] +// #[unstable(feature = "byte_str", issue = "134915")] // impl<'a> From<&'a mut ByteStr> for &'a mut [u8] { // #[inline] // fn from(s: &'a mut ByteStr) -> Self { @@ -373,7 +600,7 @@ impl<'a> Default for &'a mut ByteStr { // Omitted due to inference failures // -// #[unstable(feature = "bstr", issue = "134915")] +// #[unstable(feature = "byte_str", issue = "134915")] // impl<'a> From<&'a str> for &'a ByteStr { // #[inline] // fn from(s: &'a str) -> Self { @@ -381,24 +608,24 @@ impl<'a> Default for &'a mut ByteStr { // } // } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl<'a> TryFrom<&'a ByteStr> for &'a str { type Error = crate::str::Utf8Error; #[inline] fn try_from(s: &'a ByteStr) -> Result { - crate::str::from_utf8(&s.0) + str::from_utf8(&s.0) } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] const impl<'a> TryFrom<&'a mut ByteStr> for &'a mut str { type Error = crate::str::Utf8Error; #[inline] fn try_from(s: &'a mut ByteStr) -> Result { - crate::str::from_utf8_mut(&mut s.0) + str::from_utf8_mut(&mut s.0) } } diff --git a/library/core/src/bstr/traits.rs b/library/core/src/byte_str/traits.rs similarity index 85% rename from library/core/src/bstr/traits.rs rename to library/core/src/byte_str/traits.rs index 1d8d0e29e9a5a..eda2be45a6992 100644 --- a/library/core/src/bstr/traits.rs +++ b/library/core/src/byte_str/traits.rs @@ -1,11 +1,11 @@ //! Trait implementations for `ByteStr`. -use crate::bstr::ByteStr; +use crate::byte_str::ByteStr; use crate::cmp::Ordering; use crate::slice::SliceIndex; use crate::{hash, ops, range}; -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl Ord for ByteStr { #[inline] fn cmp(&self, other: &ByteStr) -> Ordering { @@ -13,7 +13,7 @@ impl Ord for ByteStr { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl PartialOrd for ByteStr { #[inline] fn partial_cmp(&self, other: &ByteStr) -> Option { @@ -21,7 +21,7 @@ impl PartialOrd for ByteStr { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl PartialEq for ByteStr { #[inline] fn eq(&self, other: &ByteStr) -> bool { @@ -29,10 +29,10 @@ impl PartialEq for ByteStr { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl Eq for ByteStr {} -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl hash::Hash for ByteStr { #[inline] fn hash(&self, state: &mut H) { @@ -42,7 +42,7 @@ impl hash::Hash for ByteStr { #[doc(hidden)] #[macro_export] -#[unstable(feature = "bstr_internals", issue = "none")] +#[unstable(feature = "byte_str_internals", issue = "none")] macro_rules! impl_partial_eq { ($lhs:ty, $rhs:ty) => { impl PartialEq<$rhs> for $lhs { @@ -64,17 +64,17 @@ macro_rules! impl_partial_eq { } #[doc(hidden)] -#[unstable(feature = "bstr_internals", issue = "none")] +#[unstable(feature = "byte_str_internals", issue = "none")] pub use impl_partial_eq; #[doc(hidden)] #[macro_export] -#[unstable(feature = "bstr_internals", issue = "none")] +#[unstable(feature = "byte_str_internals", issue = "none")] macro_rules! impl_partial_eq_ord { ($lhs:ty, $rhs:ty) => { - $crate::bstr::impl_partial_eq!($lhs, $rhs); + $crate::byte_str::impl_partial_eq!($lhs, $rhs); - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] impl PartialOrd<$rhs> for $lhs { #[inline] fn partial_cmp(&self, other: &$rhs) -> Option { @@ -83,7 +83,7 @@ macro_rules! impl_partial_eq_ord { } } - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] impl PartialOrd<$lhs> for $rhs { #[inline] fn partial_cmp(&self, other: &$lhs) -> Option { @@ -95,15 +95,15 @@ macro_rules! impl_partial_eq_ord { } #[doc(hidden)] -#[unstable(feature = "bstr_internals", issue = "none")] +#[unstable(feature = "byte_str_internals", issue = "none")] pub use impl_partial_eq_ord; #[doc(hidden)] #[macro_export] -#[unstable(feature = "bstr_internals", issue = "none")] +#[unstable(feature = "byte_str_internals", issue = "none")] macro_rules! impl_partial_eq_n { ($lhs:ty, $rhs:ty) => { - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] impl PartialEq<$rhs> for $lhs { #[inline] fn eq(&self, other: &$rhs) -> bool { @@ -112,7 +112,7 @@ macro_rules! impl_partial_eq_n { } } - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] impl PartialEq<$lhs> for $rhs { #[inline] fn eq(&self, other: &$lhs) -> bool { @@ -124,7 +124,7 @@ macro_rules! impl_partial_eq_n { } #[doc(hidden)] -#[unstable(feature = "bstr_internals", issue = "none")] +#[unstable(feature = "byte_str_internals", issue = "none")] pub use impl_partial_eq_n; // PartialOrd with `[u8]` omitted to avoid inference failures @@ -140,7 +140,7 @@ impl_partial_eq_n!(ByteStr, [u8; N]); // PartialOrd with `[u8; N]` omitted to avoid inference failures impl_partial_eq_n!(ByteStr, &[u8; N]); -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl ops::Index for ByteStr where I: SliceIndex, @@ -153,7 +153,7 @@ where } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] impl ops::IndexMut for ByteStr where I: SliceIndex, @@ -164,7 +164,7 @@ where } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] unsafe impl SliceIndex for ops::RangeFull { type Output = ByteStr; #[inline] @@ -193,7 +193,7 @@ unsafe impl SliceIndex for ops::RangeFull { } } -#[unstable(feature = "bstr", issue = "134915")] +#[unstable(feature = "byte_str", issue = "134915")] unsafe impl SliceIndex for usize { type Output = u8; #[inline] @@ -226,7 +226,7 @@ unsafe impl SliceIndex for usize { macro_rules! impl_slice_index { ($index:ty) => { - #[unstable(feature = "bstr", issue = "134915")] + #[unstable(feature = "byte_str", issue = "134915")] unsafe impl SliceIndex for $index { type Output = ByteStr; #[inline] diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index 126ab37bc0b71..411fe3488fb2b 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -686,8 +686,8 @@ unsafe impl CloneToUninit for crate::ffi::CStr { } } -#[unstable(feature = "bstr", issue = "134915")] -unsafe impl CloneToUninit for crate::bstr::ByteStr { +#[unstable(feature = "byte_str", issue = "134915")] +unsafe impl CloneToUninit for crate::byte_str::ByteStr { #[inline] #[cfg_attr(debug_assertions, track_caller)] unsafe fn clone_to_uninit(&self, dst: *mut u8) { diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index e5b1f8088a5bf..80e55b96c94a5 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -171,7 +171,7 @@ impl fmt::Display for FromBytesUntilNulError { #[stable(feature = "cstr_debug", since = "1.3.0")] impl fmt::Debug for CStr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(crate::bstr::ByteStr::from_bytes(self.to_bytes()), f) + fmt::Debug::fmt(crate::byte_str::ByteStr::from_bytes(self.to_bytes()), f) } } @@ -652,7 +652,7 @@ impl CStr { it returns an object that can be displayed"] #[inline] pub fn display(&self) -> impl fmt::Display { - crate::bstr::ByteStr::from_bytes(self.to_bytes()) + crate::byte_str::ByteStr::from_bytes(self.to_bytes()) } /// Returns the same string as a string slice `&CStr`. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 4fbd3c6dc2142..a4875529e44f8 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -86,7 +86,7 @@ // Library features: // tidy-alphabetical-start #![feature(asm_experimental_arch)] -#![feature(bstr_internals)] +#![feature(byte_str_internals)] #![feature(cfg_target_has_reliable_f16_f128)] #![feature(const_carrying_mul_add)] #![feature(const_cmp)] @@ -292,8 +292,8 @@ pub mod ascii; pub mod asserting; #[unstable(feature = "async_iterator", issue = "79024")] pub mod async_iter; -#[unstable(feature = "bstr", issue = "134915")] -pub mod bstr; +#[unstable(feature = "byte_str", issue = "134915")] +pub mod byte_str; pub mod cell; pub mod char; pub mod ffi; diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f73f0c5390629..a38217487b9cb 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -6,6 +6,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use crate::byte_str::ByteStr; use crate::clone::TrivialClone; use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::intrinsics::{exact_div, unchecked_sub}; @@ -5380,6 +5381,24 @@ impl [T] { } } +impl [u8] { + /// Casts a byte slice as a byte string. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn as_byte_str(&self) -> &ByteStr { + ByteStr::from_bytes(self) + } + + /// Casts a mutable byte slice as a byte string. + #[unstable(feature = "byte_str", issue = "134915")] + #[inline] + #[rustc_const_unstable(feature = "byte_str", issue = "134915")] + pub const fn as_mut_byte_str(&mut self) -> &mut ByteStr { + ByteStr::from_bytes_mut(self) + } +} + impl [MaybeUninit] { /// Transmutes the mutable uninitialized slice to a mutable uninitialized slice of /// another type, ensuring alignment of the types is maintained. diff --git a/library/coretests/tests/bstr.rs b/library/coretests/tests/byte_str.rs similarity index 99% rename from library/coretests/tests/bstr.rs rename to library/coretests/tests/byte_str.rs index dffc7e3f03494..bc90b348446bf 100644 --- a/library/coretests/tests/bstr.rs +++ b/library/coretests/tests/byte_str.rs @@ -1,4 +1,4 @@ -use core::bstr::ByteStr; +use core::byte_str::ByteStr; #[test] fn test_debug() { diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index c993c947929cd..3cffa2171c6f6 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -9,7 +9,7 @@ #![feature(async_iter_from_iter)] #![feature(async_iterator)] #![feature(borrowed_buf_init)] -#![feature(bstr)] +#![feature(byte_str)] #![feature(casefold)] #![feature(cfg_overflow_checks)] #![feature(cfg_target_has_reliable_f16_f128)] @@ -177,7 +177,7 @@ mod asserting; mod async_iter; mod atomic; mod bool; -mod bstr; +mod byte_str; mod cell; mod char; mod clone; diff --git a/library/std/src/bstr.rs b/library/std/src/bstr.rs deleted file mode 100644 index dd49177162833..0000000000000 --- a/library/std/src/bstr.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! The `ByteStr` and `ByteString` types and trait implementations. - -#[unstable(feature = "bstr", issue = "134915")] -pub use alloc::bstr::{ByteStr, ByteString}; diff --git a/library/std/src/byte_str.rs b/library/std/src/byte_str.rs new file mode 100644 index 0000000000000..48703b52ece21 --- /dev/null +++ b/library/std/src/byte_str.rs @@ -0,0 +1,4 @@ +//! The `ByteStr` and `ByteString` types and trait implementations. + +#[unstable(feature = "byte_str", issue = "134915")] +pub use alloc::byte_str::{ByteStr, ByteString}; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 92eccc27ee05d..20db7b4a84d58 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -319,8 +319,8 @@ // Library features (core): // tidy-alphabetical-start #![feature(borrowed_buf_init)] -#![feature(bstr)] -#![feature(bstr_internals)] +#![feature(byte_str)] +#![feature(byte_str_internals)] #![feature(c_size_t)] #![feature(can_vector)] #![feature(cast_maybe_uninit)] @@ -628,8 +628,8 @@ pub mod f64; pub mod thread; pub mod ascii; pub mod backtrace; -#[unstable(feature = "bstr", issue = "134915")] -pub mod bstr; +#[unstable(feature = "byte_str", issue = "134915")] +pub mod byte_str; pub mod collections; pub mod env; pub mod error; diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 3daddc2d34323..16d89887963e6 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -1,4 +1,4 @@ -use crate::bstr::ByteStr; +use crate::byte_str::ByteStr; use crate::ffi::OsStr; #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))] use crate::os::net::linux_ext; @@ -260,7 +260,7 @@ impl SocketAddr { { AddressKind::Unnamed } else if self.addr.sun_path[0] == 0 { - AddressKind::Abstract(ByteStr::from_bytes(&path[1..len])) + AddressKind::Abstract(ByteStr::new(&path[1..len])) } else { // linux adds a trailing NUL and counts it in the length, freebsd, netbsd // and qnx do not, and a caller may bind(2) without one either. unix(7) diff --git a/library/std/src/os/windows/net/addr.rs b/library/std/src/os/windows/net/addr.rs index c330432039a8f..5f6b93e56e723 100644 --- a/library/std/src/os/windows/net/addr.rs +++ b/library/std/src/os/windows/net/addr.rs @@ -1,5 +1,5 @@ #![unstable(feature = "windows_unix_domain_sockets", issue = "150487")] -use crate::bstr::ByteStr; +use crate::byte_str::ByteStr; use crate::ffi::OsStr; use crate::path::Path; #[cfg(not(doc))] diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 048e5def1369b..040a9568ca1f6 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -4,7 +4,7 @@ use core::clone::CloneToUninit; use crate::borrow::Cow; -use crate::bstr::ByteStr; +use crate::byte_str::ByteStr; use crate::collections::TryReserveError; use crate::rc::Rc; use crate::sync::Arc; diff --git a/library/std/src/sys/platform_version/darwin/mod.rs b/library/std/src/sys/platform_version/darwin/mod.rs index 4756716452c88..7e82c04fce76c 100644 --- a/library/std/src/sys/platform_version/darwin/mod.rs +++ b/library/std/src/sys/platform_version/darwin/mod.rs @@ -3,7 +3,7 @@ use self::core_foundation::{ kCFPropertyListImmutable, kCFStringEncodingUTF8, }; use crate::borrow::Cow; -use crate::bstr::ByteStr; +use crate::byte_str::ByteStr; use crate::ffi::{CStr, c_char}; use crate::num::{NonZero, ParseIntError}; use crate::path::{Path, PathBuf}; diff --git a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr index 71a1360cb5a22..f91311075a7df 100644 --- a/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr +++ b/tests/ui/associated-types/associated-types-in-ambiguous-context.stderr @@ -31,9 +31,6 @@ LL | type X = std::ops::Deref::Target; help: use fully-qualified syntax | LL - type X = std::ops::Deref::Target; -LL + type X = ::Target; - | -LL - type X = std::ops::Deref::Target; LL + type X = ::Target; | LL - type X = std::ops::Deref::Target; @@ -42,6 +39,9 @@ LL + type X = ::Target; LL - type X = std::ops::Deref::Target; LL + type X = as Deref>::Target; | +LL - type X = std::ops::Deref::Target; +LL + type X = as Deref>::Target; + | = and N other candidates error[E0223]: ambiguous associated type diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index 65faaec41258e..d40d511ab5a2f 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr @@ -9,7 +9,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `Vec<{integer}>` to implement `Index` diff --git a/tests/ui/indexing/indexing-integral-types.stderr b/tests/ui/indexing/indexing-integral-types.stderr index 604161325afcb..9577444703f83 100644 --- a/tests/ui/indexing/indexing-integral-types.stderr +++ b/tests/ui/indexing/indexing-integral-types.stderr @@ -9,7 +9,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `Vec` to implement `Index` @@ -25,7 +25,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `Vec` to implement `Index` @@ -41,7 +41,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `Vec` to implement `Index` @@ -57,7 +57,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `Vec` to implement `Index` @@ -73,7 +73,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `[u8]` to implement `Index` @@ -89,7 +89,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `[u8]` to implement `Index` @@ -105,7 +105,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `[u8]` to implement `Index` @@ -121,7 +121,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `[u8]` to implement `Index` diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index 9e974c8c9bbcc..5c93fcd948a24 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -9,7 +9,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `[{integer}]` to implement `Index` diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index 61d4866f5618b..a5a3d8c000e76 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -9,7 +9,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `[i32]` to implement `Index` @@ -25,10 +25,10 @@ help: `RangeTo` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` - ::: $SRC_DIR/core/src/bstr/traits.rs:LL:COL + ::: $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: in this macro invocation --> $SRC_DIR/core/src/str/traits.rs:LL:COL diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index 84f698a6e6625..b515a2e9dfb76 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -11,7 +11,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `str` to implement `Index<{integer}>` @@ -31,7 +31,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` note: required by a bound in `core::str::::get` @@ -52,7 +52,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` note: required by a bound in `core::str::::get_unchecked` diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index 87b78915075d2..89582c437c917 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -35,7 +35,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `str` to implement `Index` @@ -55,7 +55,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` note: required by a bound in `core::str::::get_mut` @@ -76,7 +76,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` note: required by a bound in `core::str::::get_unchecked_mut` diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index cee5ffcb2ae8c..7bf3b4ffaf275 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -9,7 +9,7 @@ help: `usize` implements trait `SliceIndex` --> $SRC_DIR/core/src/slice/index.rs:LL:COL | = note: `SliceIndex<[T]>` - --> $SRC_DIR/core/src/bstr/traits.rs:LL:COL + --> $SRC_DIR/core/src/byte_str/traits.rs:LL:COL | = note: `SliceIndex` = note: required for `[{integer}]` to implement `Index<&usize>`