1cdb3e2c8Sopenharmony_ciuse std::borrow::Borrow; 2cdb3e2c8Sopenharmony_ciuse std::borrow::Cow; 3cdb3e2c8Sopenharmony_ciuse std::borrow::ToOwned; 4cdb3e2c8Sopenharmony_ciuse std::ffi::OsStr; 5cdb3e2c8Sopenharmony_ciuse std::ffi::OsString; 6cdb3e2c8Sopenharmony_ciuse std::fmt; 7cdb3e2c8Sopenharmony_ciuse std::fmt::Debug; 8cdb3e2c8Sopenharmony_ciuse std::fmt::Display; 9cdb3e2c8Sopenharmony_ciuse std::fmt::Formatter; 10cdb3e2c8Sopenharmony_ciuse std::mem; 11cdb3e2c8Sopenharmony_ciuse std::ops::Deref; 12cdb3e2c8Sopenharmony_ciuse std::ops::Index; 13cdb3e2c8Sopenharmony_ciuse std::ops::Range; 14cdb3e2c8Sopenharmony_ciuse std::ops::RangeFrom; 15cdb3e2c8Sopenharmony_ciuse std::ops::RangeFull; 16cdb3e2c8Sopenharmony_ciuse std::ops::RangeInclusive; 17cdb3e2c8Sopenharmony_ciuse std::ops::RangeTo; 18cdb3e2c8Sopenharmony_ciuse std::ops::RangeToInclusive; 19cdb3e2c8Sopenharmony_ciuse std::result; 20cdb3e2c8Sopenharmony_ciuse std::str; 21cdb3e2c8Sopenharmony_ci 22cdb3e2c8Sopenharmony_ci#[cfg(feature = "memchr")] 23cdb3e2c8Sopenharmony_ciuse memchr::memmem::find; 24cdb3e2c8Sopenharmony_ci#[cfg(feature = "memchr")] 25cdb3e2c8Sopenharmony_ciuse memchr::memmem::rfind; 26cdb3e2c8Sopenharmony_ci 27cdb3e2c8Sopenharmony_ciuse super::imp; 28cdb3e2c8Sopenharmony_ciuse super::imp::raw; 29cdb3e2c8Sopenharmony_ciuse super::iter::Split; 30cdb3e2c8Sopenharmony_ciuse super::pattern::Encoded as EncodedPattern; 31cdb3e2c8Sopenharmony_ciuse super::private; 32cdb3e2c8Sopenharmony_ciuse super::Pattern; 33cdb3e2c8Sopenharmony_ci 34cdb3e2c8Sopenharmony_ciif_checked_conversions! { 35cdb3e2c8Sopenharmony_ci use super::EncodingError; 36cdb3e2c8Sopenharmony_ci use super::Result; 37cdb3e2c8Sopenharmony_ci} 38cdb3e2c8Sopenharmony_ci 39cdb3e2c8Sopenharmony_ci#[cfg(not(feature = "memchr"))] 40cdb3e2c8Sopenharmony_cifn find(string: &[u8], pat: &[u8]) -> Option<usize> { 41cdb3e2c8Sopenharmony_ci (0..=string.len().checked_sub(pat.len())?) 42cdb3e2c8Sopenharmony_ci .find(|&x| string[x..].starts_with(pat)) 43cdb3e2c8Sopenharmony_ci} 44cdb3e2c8Sopenharmony_ci 45cdb3e2c8Sopenharmony_ci#[cfg(not(feature = "memchr"))] 46cdb3e2c8Sopenharmony_cifn rfind(string: &[u8], pat: &[u8]) -> Option<usize> { 47cdb3e2c8Sopenharmony_ci (pat.len()..=string.len()) 48cdb3e2c8Sopenharmony_ci .rfind(|&x| string[..x].ends_with(pat)) 49cdb3e2c8Sopenharmony_ci .map(|x| x - pat.len()) 50cdb3e2c8Sopenharmony_ci} 51cdb3e2c8Sopenharmony_ci 52cdb3e2c8Sopenharmony_ci#[allow(clippy::missing_safety_doc)] 53cdb3e2c8Sopenharmony_ciunsafe trait TransmuteBox { 54cdb3e2c8Sopenharmony_ci fn transmute_box<R>(self: Box<Self>) -> Box<R> 55cdb3e2c8Sopenharmony_ci where 56cdb3e2c8Sopenharmony_ci R: ?Sized + TransmuteBox, 57cdb3e2c8Sopenharmony_ci { 58cdb3e2c8Sopenharmony_ci let value = Box::into_raw(self); 59cdb3e2c8Sopenharmony_ci // SAFETY: This trait is only implemented for types that can be 60cdb3e2c8Sopenharmony_ci // transmuted. 61cdb3e2c8Sopenharmony_ci unsafe { Box::from_raw(mem::transmute_copy(&value)) } 62cdb3e2c8Sopenharmony_ci } 63cdb3e2c8Sopenharmony_ci} 64cdb3e2c8Sopenharmony_ci 65cdb3e2c8Sopenharmony_ci// SAFETY: This struct has a layout that makes this operation safe. 66cdb3e2c8Sopenharmony_ciunsafe impl TransmuteBox for RawOsStr {} 67cdb3e2c8Sopenharmony_ciunsafe impl TransmuteBox for [u8] {} 68cdb3e2c8Sopenharmony_ci 69cdb3e2c8Sopenharmony_ci/// A container for borrowed byte strings converted by this crate. 70cdb3e2c8Sopenharmony_ci/// 71cdb3e2c8Sopenharmony_ci/// This wrapper is intended to prevent violating the invariants of the 72cdb3e2c8Sopenharmony_ci/// [unspecified encoding] used by this crate and minimize encoding 73cdb3e2c8Sopenharmony_ci/// conversions. 74cdb3e2c8Sopenharmony_ci/// 75cdb3e2c8Sopenharmony_ci/// # Indices 76cdb3e2c8Sopenharmony_ci/// 77cdb3e2c8Sopenharmony_ci/// Methods of this struct that accept indices require that the index lie on a 78cdb3e2c8Sopenharmony_ci/// UTF-8 boundary. Although it is possible to manipulate platform strings 79cdb3e2c8Sopenharmony_ci/// based on other indices, this crate currently does not support them for 80cdb3e2c8Sopenharmony_ci/// slicing methods. They would add significant complication to the 81cdb3e2c8Sopenharmony_ci/// implementation and are generally not necessary. However, all indices 82cdb3e2c8Sopenharmony_ci/// returned by this struct can be used for slicing. 83cdb3e2c8Sopenharmony_ci/// 84cdb3e2c8Sopenharmony_ci/// On Unix, all indices are permitted, to avoid false positives. However, 85cdb3e2c8Sopenharmony_ci/// relying on this implementation detail is discouraged. Platform-specific 86cdb3e2c8Sopenharmony_ci/// indices are error-prone. 87cdb3e2c8Sopenharmony_ci/// 88cdb3e2c8Sopenharmony_ci/// # Complexity 89cdb3e2c8Sopenharmony_ci/// 90cdb3e2c8Sopenharmony_ci/// All searching methods have worst-case multiplicative time complexity (i.e., 91cdb3e2c8Sopenharmony_ci/// `O(self.raw_len() * pat.len())`). Enabling the "memchr" feature allows 92cdb3e2c8Sopenharmony_ci/// these methods to instead run in linear time in the worst case (documented 93cdb3e2c8Sopenharmony_ci/// for [`memchr::memmem::find`][memchr complexity]). 94cdb3e2c8Sopenharmony_ci/// 95cdb3e2c8Sopenharmony_ci/// # Safety 96cdb3e2c8Sopenharmony_ci/// 97cdb3e2c8Sopenharmony_ci/// Although this type is annotated with `#[repr(transparent)]`, the inner 98cdb3e2c8Sopenharmony_ci/// representation is not stable. Transmuting between this type and any other 99cdb3e2c8Sopenharmony_ci/// causes immediate undefined behavior. 100cdb3e2c8Sopenharmony_ci/// 101cdb3e2c8Sopenharmony_ci/// [memchr complexity]: memchr::memmem::find#complexity 102cdb3e2c8Sopenharmony_ci/// [unspecified encoding]: super#encoding 103cdb3e2c8Sopenharmony_ci#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)] 104cdb3e2c8Sopenharmony_ci#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "raw_os_str")))] 105cdb3e2c8Sopenharmony_ci#[repr(transparent)] 106cdb3e2c8Sopenharmony_cipub struct RawOsStr([u8]); 107cdb3e2c8Sopenharmony_ci 108cdb3e2c8Sopenharmony_ciimpl RawOsStr { 109cdb3e2c8Sopenharmony_ci const fn from_inner(string: &[u8]) -> &Self { 110cdb3e2c8Sopenharmony_ci // SAFETY: This struct has a layout that makes this operation safe. 111cdb3e2c8Sopenharmony_ci unsafe { mem::transmute(string) } 112cdb3e2c8Sopenharmony_ci } 113cdb3e2c8Sopenharmony_ci 114cdb3e2c8Sopenharmony_ci /// Converts a platform-native string into a representation that can be 115cdb3e2c8Sopenharmony_ci /// more easily manipulated. 116cdb3e2c8Sopenharmony_ci /// 117cdb3e2c8Sopenharmony_ci /// This method performs the necessary conversion immediately, so it can be 118cdb3e2c8Sopenharmony_ci /// expensive to call. It is recommended to continue using the returned 119cdb3e2c8Sopenharmony_ci /// instance as long as possible (instead of the original [`OsStr`]), to 120cdb3e2c8Sopenharmony_ci /// avoid repeated conversions. 121cdb3e2c8Sopenharmony_ci /// 122cdb3e2c8Sopenharmony_ci /// # Examples 123cdb3e2c8Sopenharmony_ci /// 124cdb3e2c8Sopenharmony_ci /// ``` 125cdb3e2c8Sopenharmony_ci /// use std::env; 126cdb3e2c8Sopenharmony_ci /// # use std::io; 127cdb3e2c8Sopenharmony_ci /// 128cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 129cdb3e2c8Sopenharmony_ci /// 130cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 131cdb3e2c8Sopenharmony_ci /// println!("{:?}", RawOsStr::new(&os_string)); 132cdb3e2c8Sopenharmony_ci /// # 133cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 134cdb3e2c8Sopenharmony_ci /// ``` 135cdb3e2c8Sopenharmony_ci #[inline] 136cdb3e2c8Sopenharmony_ci #[must_use] 137cdb3e2c8Sopenharmony_ci pub fn new(string: &OsStr) -> Cow<'_, Self> { 138cdb3e2c8Sopenharmony_ci match imp::os_str_to_bytes(string) { 139cdb3e2c8Sopenharmony_ci Cow::Borrowed(string) => Cow::Borrowed(Self::from_inner(string)), 140cdb3e2c8Sopenharmony_ci Cow::Owned(string) => Cow::Owned(RawOsString(string)), 141cdb3e2c8Sopenharmony_ci } 142cdb3e2c8Sopenharmony_ci } 143cdb3e2c8Sopenharmony_ci 144cdb3e2c8Sopenharmony_ci /// Wraps a string, without copying or encoding conversion. 145cdb3e2c8Sopenharmony_ci /// 146cdb3e2c8Sopenharmony_ci /// This method is much more efficient than [`RawOsStr::new`], since the 147cdb3e2c8Sopenharmony_ci /// [encoding] used by this crate is compatible with UTF-8. 148cdb3e2c8Sopenharmony_ci /// 149cdb3e2c8Sopenharmony_ci /// # Examples 150cdb3e2c8Sopenharmony_ci /// 151cdb3e2c8Sopenharmony_ci /// ``` 152cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 153cdb3e2c8Sopenharmony_ci /// 154cdb3e2c8Sopenharmony_ci /// let string = "foobar"; 155cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str(string); 156cdb3e2c8Sopenharmony_ci /// assert_eq!(string, raw); 157cdb3e2c8Sopenharmony_ci /// ``` 158cdb3e2c8Sopenharmony_ci /// 159cdb3e2c8Sopenharmony_ci /// [encoding]: super#encoding 160cdb3e2c8Sopenharmony_ci #[allow(clippy::should_implement_trait)] 161cdb3e2c8Sopenharmony_ci #[inline] 162cdb3e2c8Sopenharmony_ci #[must_use] 163cdb3e2c8Sopenharmony_ci pub fn from_str(string: &str) -> &Self { 164cdb3e2c8Sopenharmony_ci Self::from_inner(string.as_bytes()) 165cdb3e2c8Sopenharmony_ci } 166cdb3e2c8Sopenharmony_ci 167cdb3e2c8Sopenharmony_ci /// Wraps a byte string, without copying or encoding conversion. 168cdb3e2c8Sopenharmony_ci /// 169cdb3e2c8Sopenharmony_ci /// # Panics 170cdb3e2c8Sopenharmony_ci /// 171cdb3e2c8Sopenharmony_ci /// Panics if the string is not valid for the [unspecified encoding] used 172cdb3e2c8Sopenharmony_ci /// by this crate. 173cdb3e2c8Sopenharmony_ci /// 174cdb3e2c8Sopenharmony_ci /// # Examples 175cdb3e2c8Sopenharmony_ci /// 176cdb3e2c8Sopenharmony_ci /// ``` 177cdb3e2c8Sopenharmony_ci /// use std::env; 178cdb3e2c8Sopenharmony_ci /// # use std::io; 179cdb3e2c8Sopenharmony_ci /// 180cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 181cdb3e2c8Sopenharmony_ci /// 182cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 183cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::new(&os_string); 184cdb3e2c8Sopenharmony_ci /// let raw_bytes = raw.as_raw_bytes(); 185cdb3e2c8Sopenharmony_ci /// assert_eq!(&*raw, RawOsStr::assert_from_raw_bytes(raw_bytes)); 186cdb3e2c8Sopenharmony_ci /// # 187cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 188cdb3e2c8Sopenharmony_ci /// ``` 189cdb3e2c8Sopenharmony_ci /// 190cdb3e2c8Sopenharmony_ci /// [unspecified encoding]: super#encoding 191cdb3e2c8Sopenharmony_ci #[inline] 192cdb3e2c8Sopenharmony_ci #[must_use = "method should not be used for validation"] 193cdb3e2c8Sopenharmony_ci #[track_caller] 194cdb3e2c8Sopenharmony_ci pub fn assert_from_raw_bytes(string: &[u8]) -> &Self { 195cdb3e2c8Sopenharmony_ci expect_encoded!(raw::validate_bytes(string)); 196cdb3e2c8Sopenharmony_ci 197cdb3e2c8Sopenharmony_ci Self::from_inner(string) 198cdb3e2c8Sopenharmony_ci } 199cdb3e2c8Sopenharmony_ci 200cdb3e2c8Sopenharmony_ci if_checked_conversions! { 201cdb3e2c8Sopenharmony_ci /// Wraps a byte string, without copying or encoding conversion. 202cdb3e2c8Sopenharmony_ci /// 203cdb3e2c8Sopenharmony_ci /// [`assert_from_raw_bytes`] should almost always be used instead. For 204cdb3e2c8Sopenharmony_ci /// more information, see [`EncodingError`]. 205cdb3e2c8Sopenharmony_ci /// 206cdb3e2c8Sopenharmony_ci /// # Errors 207cdb3e2c8Sopenharmony_ci /// 208cdb3e2c8Sopenharmony_ci /// See documentation for [`EncodingError`]. 209cdb3e2c8Sopenharmony_ci /// 210cdb3e2c8Sopenharmony_ci /// # Examples 211cdb3e2c8Sopenharmony_ci /// 212cdb3e2c8Sopenharmony_ci /// ``` 213cdb3e2c8Sopenharmony_ci /// use std::env; 214cdb3e2c8Sopenharmony_ci /// # use std::io; 215cdb3e2c8Sopenharmony_ci /// 216cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 217cdb3e2c8Sopenharmony_ci /// 218cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 219cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::new(&os_string); 220cdb3e2c8Sopenharmony_ci /// assert_eq!(Ok(&*raw), RawOsStr::from_raw_bytes(raw.as_raw_bytes())); 221cdb3e2c8Sopenharmony_ci /// # 222cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 223cdb3e2c8Sopenharmony_ci /// ``` 224cdb3e2c8Sopenharmony_ci /// 225cdb3e2c8Sopenharmony_ci /// [`assert_from_raw_bytes`]: Self::assert_from_raw_bytes 226cdb3e2c8Sopenharmony_ci #[cfg_attr( 227cdb3e2c8Sopenharmony_ci os_str_bytes_docs_rs, 228cdb3e2c8Sopenharmony_ci doc(cfg(feature = "checked_conversions")) 229cdb3e2c8Sopenharmony_ci )] 230cdb3e2c8Sopenharmony_ci #[inline] 231cdb3e2c8Sopenharmony_ci pub fn from_raw_bytes(string: &[u8]) -> Result<&Self> { 232cdb3e2c8Sopenharmony_ci raw::validate_bytes(string) 233cdb3e2c8Sopenharmony_ci .map(|()| Self::from_inner(string)) 234cdb3e2c8Sopenharmony_ci .map_err(EncodingError) 235cdb3e2c8Sopenharmony_ci } 236cdb3e2c8Sopenharmony_ci } 237cdb3e2c8Sopenharmony_ci 238cdb3e2c8Sopenharmony_ci /// Wraps a byte string, without copying or encoding conversion. 239cdb3e2c8Sopenharmony_ci /// 240cdb3e2c8Sopenharmony_ci /// # Safety 241cdb3e2c8Sopenharmony_ci /// 242cdb3e2c8Sopenharmony_ci /// The string must be valid for the [unspecified encoding] used by this 243cdb3e2c8Sopenharmony_ci /// crate. 244cdb3e2c8Sopenharmony_ci /// 245cdb3e2c8Sopenharmony_ci /// # Examples 246cdb3e2c8Sopenharmony_ci /// 247cdb3e2c8Sopenharmony_ci /// ``` 248cdb3e2c8Sopenharmony_ci /// use std::env; 249cdb3e2c8Sopenharmony_ci /// # use std::io; 250cdb3e2c8Sopenharmony_ci /// 251cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 252cdb3e2c8Sopenharmony_ci /// 253cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 254cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::new(&os_string); 255cdb3e2c8Sopenharmony_ci /// let raw_bytes = raw.as_raw_bytes(); 256cdb3e2c8Sopenharmony_ci /// assert_eq!(&*raw, unsafe { 257cdb3e2c8Sopenharmony_ci /// RawOsStr::from_raw_bytes_unchecked(raw_bytes) 258cdb3e2c8Sopenharmony_ci /// }); 259cdb3e2c8Sopenharmony_ci /// # 260cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 261cdb3e2c8Sopenharmony_ci /// ``` 262cdb3e2c8Sopenharmony_ci /// 263cdb3e2c8Sopenharmony_ci /// [unspecified encoding]: super#encoding 264cdb3e2c8Sopenharmony_ci #[inline] 265cdb3e2c8Sopenharmony_ci #[must_use] 266cdb3e2c8Sopenharmony_ci #[track_caller] 267cdb3e2c8Sopenharmony_ci pub unsafe fn from_raw_bytes_unchecked(string: &[u8]) -> &Self { 268cdb3e2c8Sopenharmony_ci if cfg!(debug_assertions) { 269cdb3e2c8Sopenharmony_ci expect_encoded!(raw::validate_bytes(string)); 270cdb3e2c8Sopenharmony_ci } 271cdb3e2c8Sopenharmony_ci 272cdb3e2c8Sopenharmony_ci Self::from_inner(string) 273cdb3e2c8Sopenharmony_ci } 274cdb3e2c8Sopenharmony_ci 275cdb3e2c8Sopenharmony_ci /// Returns the byte string stored by this container. 276cdb3e2c8Sopenharmony_ci /// 277cdb3e2c8Sopenharmony_ci /// The returned string will use an [unspecified encoding]. 278cdb3e2c8Sopenharmony_ci /// 279cdb3e2c8Sopenharmony_ci /// # Examples 280cdb3e2c8Sopenharmony_ci /// 281cdb3e2c8Sopenharmony_ci /// ``` 282cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 283cdb3e2c8Sopenharmony_ci /// 284cdb3e2c8Sopenharmony_ci /// let string = "foobar"; 285cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str(string); 286cdb3e2c8Sopenharmony_ci /// assert_eq!(string.as_bytes(), raw.as_raw_bytes()); 287cdb3e2c8Sopenharmony_ci /// ``` 288cdb3e2c8Sopenharmony_ci /// 289cdb3e2c8Sopenharmony_ci /// [unspecified encoding]: super#encoding 290cdb3e2c8Sopenharmony_ci #[inline] 291cdb3e2c8Sopenharmony_ci #[must_use] 292cdb3e2c8Sopenharmony_ci pub fn as_raw_bytes(&self) -> &[u8] { 293cdb3e2c8Sopenharmony_ci &self.0 294cdb3e2c8Sopenharmony_ci } 295cdb3e2c8Sopenharmony_ci 296cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::contains`]. 297cdb3e2c8Sopenharmony_ci /// 298cdb3e2c8Sopenharmony_ci /// # Examples 299cdb3e2c8Sopenharmony_ci /// 300cdb3e2c8Sopenharmony_ci /// ``` 301cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 302cdb3e2c8Sopenharmony_ci /// 303cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 304cdb3e2c8Sopenharmony_ci /// assert!(raw.contains("oo")); 305cdb3e2c8Sopenharmony_ci /// assert!(!raw.contains("of")); 306cdb3e2c8Sopenharmony_ci /// ``` 307cdb3e2c8Sopenharmony_ci #[inline] 308cdb3e2c8Sopenharmony_ci #[must_use] 309cdb3e2c8Sopenharmony_ci pub fn contains<P>(&self, pat: P) -> bool 310cdb3e2c8Sopenharmony_ci where 311cdb3e2c8Sopenharmony_ci P: Pattern, 312cdb3e2c8Sopenharmony_ci { 313cdb3e2c8Sopenharmony_ci self.find(pat).is_some() 314cdb3e2c8Sopenharmony_ci } 315cdb3e2c8Sopenharmony_ci 316cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::ends_with`]. 317cdb3e2c8Sopenharmony_ci /// 318cdb3e2c8Sopenharmony_ci /// # Examples 319cdb3e2c8Sopenharmony_ci /// 320cdb3e2c8Sopenharmony_ci /// ``` 321cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 322cdb3e2c8Sopenharmony_ci /// 323cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 324cdb3e2c8Sopenharmony_ci /// assert!(raw.ends_with("bar")); 325cdb3e2c8Sopenharmony_ci /// assert!(!raw.ends_with("foo")); 326cdb3e2c8Sopenharmony_ci /// ``` 327cdb3e2c8Sopenharmony_ci #[inline] 328cdb3e2c8Sopenharmony_ci #[must_use] 329cdb3e2c8Sopenharmony_ci pub fn ends_with<P>(&self, pat: P) -> bool 330cdb3e2c8Sopenharmony_ci where 331cdb3e2c8Sopenharmony_ci P: Pattern, 332cdb3e2c8Sopenharmony_ci { 333cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 334cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 335cdb3e2c8Sopenharmony_ci 336cdb3e2c8Sopenharmony_ci self.0.ends_with(pat) 337cdb3e2c8Sopenharmony_ci } 338cdb3e2c8Sopenharmony_ci 339cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::ends_with`] but accepts this type for the pattern. 340cdb3e2c8Sopenharmony_ci /// 341cdb3e2c8Sopenharmony_ci /// # Examples 342cdb3e2c8Sopenharmony_ci /// 343cdb3e2c8Sopenharmony_ci /// ``` 344cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 345cdb3e2c8Sopenharmony_ci /// 346cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 347cdb3e2c8Sopenharmony_ci /// assert!(raw.ends_with_os(RawOsStr::from_str("bar"))); 348cdb3e2c8Sopenharmony_ci /// assert!(!raw.ends_with_os(RawOsStr::from_str("foo"))); 349cdb3e2c8Sopenharmony_ci /// ``` 350cdb3e2c8Sopenharmony_ci #[inline] 351cdb3e2c8Sopenharmony_ci #[must_use] 352cdb3e2c8Sopenharmony_ci pub fn ends_with_os(&self, pat: &Self) -> bool { 353cdb3e2c8Sopenharmony_ci raw::ends_with(&self.0, &pat.0) 354cdb3e2c8Sopenharmony_ci } 355cdb3e2c8Sopenharmony_ci 356cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::find`]. 357cdb3e2c8Sopenharmony_ci /// 358cdb3e2c8Sopenharmony_ci /// # Examples 359cdb3e2c8Sopenharmony_ci /// 360cdb3e2c8Sopenharmony_ci /// ``` 361cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 362cdb3e2c8Sopenharmony_ci /// 363cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 364cdb3e2c8Sopenharmony_ci /// assert_eq!(Some(1), raw.find("o")); 365cdb3e2c8Sopenharmony_ci /// assert_eq!(None, raw.find("of")); 366cdb3e2c8Sopenharmony_ci /// ``` 367cdb3e2c8Sopenharmony_ci #[inline] 368cdb3e2c8Sopenharmony_ci #[must_use] 369cdb3e2c8Sopenharmony_ci pub fn find<P>(&self, pat: P) -> Option<usize> 370cdb3e2c8Sopenharmony_ci where 371cdb3e2c8Sopenharmony_ci P: Pattern, 372cdb3e2c8Sopenharmony_ci { 373cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 374cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 375cdb3e2c8Sopenharmony_ci 376cdb3e2c8Sopenharmony_ci find(&self.0, pat) 377cdb3e2c8Sopenharmony_ci } 378cdb3e2c8Sopenharmony_ci 379cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::is_empty`]. 380cdb3e2c8Sopenharmony_ci /// 381cdb3e2c8Sopenharmony_ci /// # Examples 382cdb3e2c8Sopenharmony_ci /// 383cdb3e2c8Sopenharmony_ci /// ``` 384cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 385cdb3e2c8Sopenharmony_ci /// 386cdb3e2c8Sopenharmony_ci /// assert!(RawOsStr::from_str("").is_empty()); 387cdb3e2c8Sopenharmony_ci /// assert!(!RawOsStr::from_str("foobar").is_empty()); 388cdb3e2c8Sopenharmony_ci /// ``` 389cdb3e2c8Sopenharmony_ci #[inline] 390cdb3e2c8Sopenharmony_ci #[must_use] 391cdb3e2c8Sopenharmony_ci pub fn is_empty(&self) -> bool { 392cdb3e2c8Sopenharmony_ci self.0.is_empty() 393cdb3e2c8Sopenharmony_ci } 394cdb3e2c8Sopenharmony_ci 395cdb3e2c8Sopenharmony_ci /// Returns the length of the byte string stored by this container. 396cdb3e2c8Sopenharmony_ci /// 397cdb3e2c8Sopenharmony_ci /// Only the following assumptions can be made about the result: 398cdb3e2c8Sopenharmony_ci /// - The length of any Unicode character is the length of its UTF-8 399cdb3e2c8Sopenharmony_ci /// representation (i.e., [`char::len_utf8`]). 400cdb3e2c8Sopenharmony_ci /// - Splitting a string at a UTF-8 boundary will return two strings with 401cdb3e2c8Sopenharmony_ci /// lengths that sum to the length of the original string. 402cdb3e2c8Sopenharmony_ci /// 403cdb3e2c8Sopenharmony_ci /// This method may return a different result than would [`OsStr::len`] 404cdb3e2c8Sopenharmony_ci /// when called on same string, since [`OsStr`] uses an unspecified 405cdb3e2c8Sopenharmony_ci /// encoding. 406cdb3e2c8Sopenharmony_ci /// 407cdb3e2c8Sopenharmony_ci /// # Examples 408cdb3e2c8Sopenharmony_ci /// 409cdb3e2c8Sopenharmony_ci /// ``` 410cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 411cdb3e2c8Sopenharmony_ci /// 412cdb3e2c8Sopenharmony_ci /// assert_eq!(6, RawOsStr::from_str("foobar").raw_len()); 413cdb3e2c8Sopenharmony_ci /// assert_eq!(0, RawOsStr::from_str("").raw_len()); 414cdb3e2c8Sopenharmony_ci /// ``` 415cdb3e2c8Sopenharmony_ci #[inline] 416cdb3e2c8Sopenharmony_ci #[must_use] 417cdb3e2c8Sopenharmony_ci pub fn raw_len(&self) -> usize { 418cdb3e2c8Sopenharmony_ci self.0.len() 419cdb3e2c8Sopenharmony_ci } 420cdb3e2c8Sopenharmony_ci 421cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::rfind`]. 422cdb3e2c8Sopenharmony_ci /// 423cdb3e2c8Sopenharmony_ci /// # Examples 424cdb3e2c8Sopenharmony_ci /// 425cdb3e2c8Sopenharmony_ci /// ``` 426cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 427cdb3e2c8Sopenharmony_ci /// 428cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 429cdb3e2c8Sopenharmony_ci /// assert_eq!(Some(2), raw.rfind("o")); 430cdb3e2c8Sopenharmony_ci /// assert_eq!(None, raw.rfind("of")); 431cdb3e2c8Sopenharmony_ci /// ``` 432cdb3e2c8Sopenharmony_ci #[inline] 433cdb3e2c8Sopenharmony_ci #[must_use] 434cdb3e2c8Sopenharmony_ci pub fn rfind<P>(&self, pat: P) -> Option<usize> 435cdb3e2c8Sopenharmony_ci where 436cdb3e2c8Sopenharmony_ci P: Pattern, 437cdb3e2c8Sopenharmony_ci { 438cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 439cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 440cdb3e2c8Sopenharmony_ci 441cdb3e2c8Sopenharmony_ci rfind(&self.0, pat) 442cdb3e2c8Sopenharmony_ci } 443cdb3e2c8Sopenharmony_ci 444cdb3e2c8Sopenharmony_ci fn split_once_raw_with<P, F>( 445cdb3e2c8Sopenharmony_ci &self, 446cdb3e2c8Sopenharmony_ci pat: &P, 447cdb3e2c8Sopenharmony_ci find_fn: F, 448cdb3e2c8Sopenharmony_ci ) -> Option<(&Self, &Self)> 449cdb3e2c8Sopenharmony_ci where 450cdb3e2c8Sopenharmony_ci F: FnOnce(&[u8], &[u8]) -> Option<usize>, 451cdb3e2c8Sopenharmony_ci P: EncodedPattern, 452cdb3e2c8Sopenharmony_ci { 453cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 454cdb3e2c8Sopenharmony_ci 455cdb3e2c8Sopenharmony_ci let index = find_fn(&self.0, pat)?; 456cdb3e2c8Sopenharmony_ci let prefix = &self.0[..index]; 457cdb3e2c8Sopenharmony_ci let suffix = &self.0[index + pat.len()..]; 458cdb3e2c8Sopenharmony_ci Some((Self::from_inner(prefix), Self::from_inner(suffix))) 459cdb3e2c8Sopenharmony_ci } 460cdb3e2c8Sopenharmony_ci 461cdb3e2c8Sopenharmony_ci pub(super) fn rsplit_once_raw<P>(&self, pat: &P) -> Option<(&Self, &Self)> 462cdb3e2c8Sopenharmony_ci where 463cdb3e2c8Sopenharmony_ci P: EncodedPattern, 464cdb3e2c8Sopenharmony_ci { 465cdb3e2c8Sopenharmony_ci self.split_once_raw_with(pat, rfind) 466cdb3e2c8Sopenharmony_ci } 467cdb3e2c8Sopenharmony_ci 468cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::rsplit_once`]. 469cdb3e2c8Sopenharmony_ci /// 470cdb3e2c8Sopenharmony_ci /// # Examples 471cdb3e2c8Sopenharmony_ci /// 472cdb3e2c8Sopenharmony_ci /// ``` 473cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 474cdb3e2c8Sopenharmony_ci /// 475cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 476cdb3e2c8Sopenharmony_ci /// assert_eq!( 477cdb3e2c8Sopenharmony_ci /// Some((RawOsStr::from_str("fo"), RawOsStr::from_str("bar"))), 478cdb3e2c8Sopenharmony_ci /// raw.rsplit_once("o"), 479cdb3e2c8Sopenharmony_ci /// ); 480cdb3e2c8Sopenharmony_ci /// assert_eq!(None, raw.rsplit_once("of")); 481cdb3e2c8Sopenharmony_ci /// ``` 482cdb3e2c8Sopenharmony_ci #[inline] 483cdb3e2c8Sopenharmony_ci #[must_use] 484cdb3e2c8Sopenharmony_ci pub fn rsplit_once<P>(&self, pat: P) -> Option<(&Self, &Self)> 485cdb3e2c8Sopenharmony_ci where 486cdb3e2c8Sopenharmony_ci P: Pattern, 487cdb3e2c8Sopenharmony_ci { 488cdb3e2c8Sopenharmony_ci self.rsplit_once_raw(&pat.__encode()) 489cdb3e2c8Sopenharmony_ci } 490cdb3e2c8Sopenharmony_ci 491cdb3e2c8Sopenharmony_ci // https://github.com/rust-lang/rust/blob/49c68bd53f90e375bfb3cbba8c1c67a9e0adb9c0/src/libcore/str/mod.rs#L2184-L2221 492cdb3e2c8Sopenharmony_ci #[cold] 493cdb3e2c8Sopenharmony_ci #[inline(never)] 494cdb3e2c8Sopenharmony_ci #[track_caller] 495cdb3e2c8Sopenharmony_ci fn index_boundary_error(&self, index: usize) -> ! { 496cdb3e2c8Sopenharmony_ci debug_assert!(raw::is_continuation(self.0[index])); 497cdb3e2c8Sopenharmony_ci 498cdb3e2c8Sopenharmony_ci let start = expect_encoded!(self.0[..index] 499cdb3e2c8Sopenharmony_ci .iter() 500cdb3e2c8Sopenharmony_ci .rposition(|&x| !raw::is_continuation(x))); 501cdb3e2c8Sopenharmony_ci let mut end = index + 1; 502cdb3e2c8Sopenharmony_ci end += self.0[end..] 503cdb3e2c8Sopenharmony_ci .iter() 504cdb3e2c8Sopenharmony_ci .take_while(|&&x| raw::is_continuation(x)) 505cdb3e2c8Sopenharmony_ci .count(); 506cdb3e2c8Sopenharmony_ci let code_point = raw::decode_code_point(&self.0[start..end]); 507cdb3e2c8Sopenharmony_ci panic!( 508cdb3e2c8Sopenharmony_ci "byte index {} is not a valid boundary; it is inside U+{:04X} \ 509cdb3e2c8Sopenharmony_ci (bytes {}..{})", 510cdb3e2c8Sopenharmony_ci index, code_point, start, end, 511cdb3e2c8Sopenharmony_ci ); 512cdb3e2c8Sopenharmony_ci } 513cdb3e2c8Sopenharmony_ci 514cdb3e2c8Sopenharmony_ci #[track_caller] 515cdb3e2c8Sopenharmony_ci fn check_bound(&self, index: usize) { 516cdb3e2c8Sopenharmony_ci if let Some(&byte) = self.0.get(index) { 517cdb3e2c8Sopenharmony_ci if raw::is_continuation(byte) { 518cdb3e2c8Sopenharmony_ci self.index_boundary_error(index); 519cdb3e2c8Sopenharmony_ci } 520cdb3e2c8Sopenharmony_ci } 521cdb3e2c8Sopenharmony_ci } 522cdb3e2c8Sopenharmony_ci 523cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::split`], but empty patterns are not accepted. 524cdb3e2c8Sopenharmony_ci /// 525cdb3e2c8Sopenharmony_ci /// # Panics 526cdb3e2c8Sopenharmony_ci /// 527cdb3e2c8Sopenharmony_ci /// Panics if the pattern is empty. 528cdb3e2c8Sopenharmony_ci /// 529cdb3e2c8Sopenharmony_ci /// # Examples 530cdb3e2c8Sopenharmony_ci /// 531cdb3e2c8Sopenharmony_ci /// ``` 532cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 533cdb3e2c8Sopenharmony_ci /// 534cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 535cdb3e2c8Sopenharmony_ci /// assert_eq!(["f", "", "bar"], *raw.split("o").collect::<Vec<_>>()); 536cdb3e2c8Sopenharmony_ci /// ``` 537cdb3e2c8Sopenharmony_ci #[inline] 538cdb3e2c8Sopenharmony_ci #[must_use] 539cdb3e2c8Sopenharmony_ci #[track_caller] 540cdb3e2c8Sopenharmony_ci pub fn split<P>(&self, pat: P) -> Split<'_, P> 541cdb3e2c8Sopenharmony_ci where 542cdb3e2c8Sopenharmony_ci P: Pattern, 543cdb3e2c8Sopenharmony_ci { 544cdb3e2c8Sopenharmony_ci Split::new(self, pat) 545cdb3e2c8Sopenharmony_ci } 546cdb3e2c8Sopenharmony_ci 547cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::split_at`]. 548cdb3e2c8Sopenharmony_ci /// 549cdb3e2c8Sopenharmony_ci /// # Panics 550cdb3e2c8Sopenharmony_ci /// 551cdb3e2c8Sopenharmony_ci /// Panics if the index is not a [valid boundary]. 552cdb3e2c8Sopenharmony_ci /// 553cdb3e2c8Sopenharmony_ci /// # Examples 554cdb3e2c8Sopenharmony_ci /// 555cdb3e2c8Sopenharmony_ci /// ``` 556cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 557cdb3e2c8Sopenharmony_ci /// 558cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 559cdb3e2c8Sopenharmony_ci /// assert_eq!( 560cdb3e2c8Sopenharmony_ci /// ((RawOsStr::from_str("fo"), RawOsStr::from_str("obar"))), 561cdb3e2c8Sopenharmony_ci /// raw.split_at(2), 562cdb3e2c8Sopenharmony_ci /// ); 563cdb3e2c8Sopenharmony_ci /// ``` 564cdb3e2c8Sopenharmony_ci /// 565cdb3e2c8Sopenharmony_ci /// [valid boundary]: #indices 566cdb3e2c8Sopenharmony_ci #[inline] 567cdb3e2c8Sopenharmony_ci #[must_use] 568cdb3e2c8Sopenharmony_ci #[track_caller] 569cdb3e2c8Sopenharmony_ci pub fn split_at(&self, mid: usize) -> (&Self, &Self) { 570cdb3e2c8Sopenharmony_ci self.check_bound(mid); 571cdb3e2c8Sopenharmony_ci 572cdb3e2c8Sopenharmony_ci let (prefix, suffix) = self.0.split_at(mid); 573cdb3e2c8Sopenharmony_ci (Self::from_inner(prefix), Self::from_inner(suffix)) 574cdb3e2c8Sopenharmony_ci } 575cdb3e2c8Sopenharmony_ci 576cdb3e2c8Sopenharmony_ci pub(super) fn split_once_raw<P>(&self, pat: &P) -> Option<(&Self, &Self)> 577cdb3e2c8Sopenharmony_ci where 578cdb3e2c8Sopenharmony_ci P: EncodedPattern, 579cdb3e2c8Sopenharmony_ci { 580cdb3e2c8Sopenharmony_ci self.split_once_raw_with(pat, find) 581cdb3e2c8Sopenharmony_ci } 582cdb3e2c8Sopenharmony_ci 583cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::split_once`]. 584cdb3e2c8Sopenharmony_ci /// 585cdb3e2c8Sopenharmony_ci /// # Examples 586cdb3e2c8Sopenharmony_ci /// 587cdb3e2c8Sopenharmony_ci /// ``` 588cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 589cdb3e2c8Sopenharmony_ci /// 590cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 591cdb3e2c8Sopenharmony_ci /// assert_eq!( 592cdb3e2c8Sopenharmony_ci /// Some((RawOsStr::from_str("f"), RawOsStr::from_str("obar"))), 593cdb3e2c8Sopenharmony_ci /// raw.split_once("o"), 594cdb3e2c8Sopenharmony_ci /// ); 595cdb3e2c8Sopenharmony_ci /// assert_eq!(None, raw.split_once("of")); 596cdb3e2c8Sopenharmony_ci /// ``` 597cdb3e2c8Sopenharmony_ci #[inline] 598cdb3e2c8Sopenharmony_ci #[must_use] 599cdb3e2c8Sopenharmony_ci pub fn split_once<P>(&self, pat: P) -> Option<(&Self, &Self)> 600cdb3e2c8Sopenharmony_ci where 601cdb3e2c8Sopenharmony_ci P: Pattern, 602cdb3e2c8Sopenharmony_ci { 603cdb3e2c8Sopenharmony_ci self.split_once_raw(&pat.__encode()) 604cdb3e2c8Sopenharmony_ci } 605cdb3e2c8Sopenharmony_ci 606cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::starts_with`]. 607cdb3e2c8Sopenharmony_ci /// 608cdb3e2c8Sopenharmony_ci /// # Examples 609cdb3e2c8Sopenharmony_ci /// 610cdb3e2c8Sopenharmony_ci /// ``` 611cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 612cdb3e2c8Sopenharmony_ci /// 613cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 614cdb3e2c8Sopenharmony_ci /// assert!(raw.starts_with("foo")); 615cdb3e2c8Sopenharmony_ci /// assert!(!raw.starts_with("bar")); 616cdb3e2c8Sopenharmony_ci /// ``` 617cdb3e2c8Sopenharmony_ci #[inline] 618cdb3e2c8Sopenharmony_ci #[must_use] 619cdb3e2c8Sopenharmony_ci pub fn starts_with<P>(&self, pat: P) -> bool 620cdb3e2c8Sopenharmony_ci where 621cdb3e2c8Sopenharmony_ci P: Pattern, 622cdb3e2c8Sopenharmony_ci { 623cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 624cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 625cdb3e2c8Sopenharmony_ci 626cdb3e2c8Sopenharmony_ci self.0.starts_with(pat) 627cdb3e2c8Sopenharmony_ci } 628cdb3e2c8Sopenharmony_ci 629cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::starts_with`] but accepts this type for the 630cdb3e2c8Sopenharmony_ci /// pattern. 631cdb3e2c8Sopenharmony_ci /// 632cdb3e2c8Sopenharmony_ci /// # Examples 633cdb3e2c8Sopenharmony_ci /// 634cdb3e2c8Sopenharmony_ci /// ``` 635cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 636cdb3e2c8Sopenharmony_ci /// 637cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("foobar"); 638cdb3e2c8Sopenharmony_ci /// assert!(raw.starts_with_os(RawOsStr::from_str("foo"))); 639cdb3e2c8Sopenharmony_ci /// assert!(!raw.starts_with_os(RawOsStr::from_str("bar"))); 640cdb3e2c8Sopenharmony_ci /// ``` 641cdb3e2c8Sopenharmony_ci #[inline] 642cdb3e2c8Sopenharmony_ci #[must_use] 643cdb3e2c8Sopenharmony_ci pub fn starts_with_os(&self, pat: &Self) -> bool { 644cdb3e2c8Sopenharmony_ci raw::starts_with(&self.0, &pat.0) 645cdb3e2c8Sopenharmony_ci } 646cdb3e2c8Sopenharmony_ci 647cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::strip_prefix`]. 648cdb3e2c8Sopenharmony_ci /// 649cdb3e2c8Sopenharmony_ci /// # Examples 650cdb3e2c8Sopenharmony_ci /// 651cdb3e2c8Sopenharmony_ci /// ``` 652cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 653cdb3e2c8Sopenharmony_ci /// 654cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("111foo1bar111"); 655cdb3e2c8Sopenharmony_ci /// assert_eq!( 656cdb3e2c8Sopenharmony_ci /// Some(RawOsStr::from_str("11foo1bar111")), 657cdb3e2c8Sopenharmony_ci /// raw.strip_prefix("1"), 658cdb3e2c8Sopenharmony_ci /// ); 659cdb3e2c8Sopenharmony_ci /// assert_eq!(None, raw.strip_prefix("o")); 660cdb3e2c8Sopenharmony_ci /// ``` 661cdb3e2c8Sopenharmony_ci #[inline] 662cdb3e2c8Sopenharmony_ci #[must_use] 663cdb3e2c8Sopenharmony_ci pub fn strip_prefix<P>(&self, pat: P) -> Option<&Self> 664cdb3e2c8Sopenharmony_ci where 665cdb3e2c8Sopenharmony_ci P: Pattern, 666cdb3e2c8Sopenharmony_ci { 667cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 668cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 669cdb3e2c8Sopenharmony_ci 670cdb3e2c8Sopenharmony_ci self.0.strip_prefix(pat).map(Self::from_inner) 671cdb3e2c8Sopenharmony_ci } 672cdb3e2c8Sopenharmony_ci 673cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::strip_suffix`]. 674cdb3e2c8Sopenharmony_ci /// 675cdb3e2c8Sopenharmony_ci /// # Examples 676cdb3e2c8Sopenharmony_ci /// 677cdb3e2c8Sopenharmony_ci /// ``` 678cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 679cdb3e2c8Sopenharmony_ci /// 680cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("111foo1bar111"); 681cdb3e2c8Sopenharmony_ci /// assert_eq!( 682cdb3e2c8Sopenharmony_ci /// Some(RawOsStr::from_str("111foo1bar11")), 683cdb3e2c8Sopenharmony_ci /// raw.strip_suffix("1"), 684cdb3e2c8Sopenharmony_ci /// ); 685cdb3e2c8Sopenharmony_ci /// assert_eq!(None, raw.strip_suffix("o")); 686cdb3e2c8Sopenharmony_ci /// ``` 687cdb3e2c8Sopenharmony_ci #[inline] 688cdb3e2c8Sopenharmony_ci #[must_use] 689cdb3e2c8Sopenharmony_ci pub fn strip_suffix<P>(&self, pat: P) -> Option<&Self> 690cdb3e2c8Sopenharmony_ci where 691cdb3e2c8Sopenharmony_ci P: Pattern, 692cdb3e2c8Sopenharmony_ci { 693cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 694cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 695cdb3e2c8Sopenharmony_ci 696cdb3e2c8Sopenharmony_ci self.0.strip_suffix(pat).map(Self::from_inner) 697cdb3e2c8Sopenharmony_ci } 698cdb3e2c8Sopenharmony_ci 699cdb3e2c8Sopenharmony_ci /// Converts this representation back to a platform-native string. 700cdb3e2c8Sopenharmony_ci /// 701cdb3e2c8Sopenharmony_ci /// When possible, use [`RawOsStrCow::into_os_str`] for a more efficient 702cdb3e2c8Sopenharmony_ci /// conversion on some platforms. 703cdb3e2c8Sopenharmony_ci /// 704cdb3e2c8Sopenharmony_ci /// # Examples 705cdb3e2c8Sopenharmony_ci /// 706cdb3e2c8Sopenharmony_ci /// ``` 707cdb3e2c8Sopenharmony_ci /// use std::env; 708cdb3e2c8Sopenharmony_ci /// # use std::io; 709cdb3e2c8Sopenharmony_ci /// 710cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 711cdb3e2c8Sopenharmony_ci /// 712cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 713cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::new(&os_string); 714cdb3e2c8Sopenharmony_ci /// assert_eq!(os_string, raw.to_os_str()); 715cdb3e2c8Sopenharmony_ci /// # 716cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 717cdb3e2c8Sopenharmony_ci /// ``` 718cdb3e2c8Sopenharmony_ci #[inline] 719cdb3e2c8Sopenharmony_ci #[must_use] 720cdb3e2c8Sopenharmony_ci pub fn to_os_str(&self) -> Cow<'_, OsStr> { 721cdb3e2c8Sopenharmony_ci expect_encoded!(imp::os_str_from_bytes(&self.0)) 722cdb3e2c8Sopenharmony_ci } 723cdb3e2c8Sopenharmony_ci 724cdb3e2c8Sopenharmony_ci /// Equivalent to [`OsStr::to_str`]. 725cdb3e2c8Sopenharmony_ci /// 726cdb3e2c8Sopenharmony_ci /// # Examples 727cdb3e2c8Sopenharmony_ci /// 728cdb3e2c8Sopenharmony_ci /// ``` 729cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 730cdb3e2c8Sopenharmony_ci /// 731cdb3e2c8Sopenharmony_ci /// let string = "foobar"; 732cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str(string); 733cdb3e2c8Sopenharmony_ci /// assert_eq!(Some(string), raw.to_str()); 734cdb3e2c8Sopenharmony_ci /// ``` 735cdb3e2c8Sopenharmony_ci #[inline] 736cdb3e2c8Sopenharmony_ci #[must_use] 737cdb3e2c8Sopenharmony_ci pub fn to_str(&self) -> Option<&str> { 738cdb3e2c8Sopenharmony_ci str::from_utf8(&self.0).ok() 739cdb3e2c8Sopenharmony_ci } 740cdb3e2c8Sopenharmony_ci 741cdb3e2c8Sopenharmony_ci /// Converts this string to the best UTF-8 representation possible. 742cdb3e2c8Sopenharmony_ci /// 743cdb3e2c8Sopenharmony_ci /// Invalid sequences will be replaced with 744cdb3e2c8Sopenharmony_ci /// [`char::REPLACEMENT_CHARACTER`]. 745cdb3e2c8Sopenharmony_ci /// 746cdb3e2c8Sopenharmony_ci /// This method may return a different result than would 747cdb3e2c8Sopenharmony_ci /// [`OsStr::to_string_lossy`] when called on same string, since [`OsStr`] 748cdb3e2c8Sopenharmony_ci /// uses an unspecified encoding. 749cdb3e2c8Sopenharmony_ci /// 750cdb3e2c8Sopenharmony_ci /// # Examples 751cdb3e2c8Sopenharmony_ci /// 752cdb3e2c8Sopenharmony_ci /// ``` 753cdb3e2c8Sopenharmony_ci /// use std::env; 754cdb3e2c8Sopenharmony_ci /// # use std::io; 755cdb3e2c8Sopenharmony_ci /// 756cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 757cdb3e2c8Sopenharmony_ci /// 758cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 759cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::new(&os_string); 760cdb3e2c8Sopenharmony_ci /// println!("{}", raw.to_str_lossy()); 761cdb3e2c8Sopenharmony_ci /// # 762cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 763cdb3e2c8Sopenharmony_ci /// ``` 764cdb3e2c8Sopenharmony_ci #[inline] 765cdb3e2c8Sopenharmony_ci #[must_use] 766cdb3e2c8Sopenharmony_ci pub fn to_str_lossy(&self) -> Cow<'_, str> { 767cdb3e2c8Sopenharmony_ci String::from_utf8_lossy(&self.0) 768cdb3e2c8Sopenharmony_ci } 769cdb3e2c8Sopenharmony_ci 770cdb3e2c8Sopenharmony_ci fn trim_matches_raw_with<P, F>(&self, pat: &P, strip_fn: F) -> &Self 771cdb3e2c8Sopenharmony_ci where 772cdb3e2c8Sopenharmony_ci F: for<'a> Fn(&'a [u8], &[u8]) -> Option<&'a [u8]>, 773cdb3e2c8Sopenharmony_ci P: EncodedPattern, 774cdb3e2c8Sopenharmony_ci { 775cdb3e2c8Sopenharmony_ci let pat = pat.__get(); 776cdb3e2c8Sopenharmony_ci if pat.is_empty() { 777cdb3e2c8Sopenharmony_ci return self; 778cdb3e2c8Sopenharmony_ci } 779cdb3e2c8Sopenharmony_ci 780cdb3e2c8Sopenharmony_ci let mut string = &self.0; 781cdb3e2c8Sopenharmony_ci while let Some(substring) = strip_fn(string, pat) { 782cdb3e2c8Sopenharmony_ci string = substring; 783cdb3e2c8Sopenharmony_ci } 784cdb3e2c8Sopenharmony_ci Self::from_inner(string) 785cdb3e2c8Sopenharmony_ci } 786cdb3e2c8Sopenharmony_ci 787cdb3e2c8Sopenharmony_ci fn trim_end_matches_raw<P>(&self, pat: &P) -> &Self 788cdb3e2c8Sopenharmony_ci where 789cdb3e2c8Sopenharmony_ci P: EncodedPattern, 790cdb3e2c8Sopenharmony_ci { 791cdb3e2c8Sopenharmony_ci self.trim_matches_raw_with(pat, <[_]>::strip_suffix) 792cdb3e2c8Sopenharmony_ci } 793cdb3e2c8Sopenharmony_ci 794cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::trim_end_matches`]. 795cdb3e2c8Sopenharmony_ci /// 796cdb3e2c8Sopenharmony_ci /// # Examples 797cdb3e2c8Sopenharmony_ci /// 798cdb3e2c8Sopenharmony_ci /// ``` 799cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 800cdb3e2c8Sopenharmony_ci /// 801cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("111foo1bar111"); 802cdb3e2c8Sopenharmony_ci /// assert_eq!("111foo1bar", raw.trim_end_matches("1")); 803cdb3e2c8Sopenharmony_ci /// assert_eq!("111foo1bar111", raw.trim_end_matches("o")); 804cdb3e2c8Sopenharmony_ci /// ``` 805cdb3e2c8Sopenharmony_ci #[inline] 806cdb3e2c8Sopenharmony_ci #[must_use] 807cdb3e2c8Sopenharmony_ci pub fn trim_end_matches<P>(&self, pat: P) -> &Self 808cdb3e2c8Sopenharmony_ci where 809cdb3e2c8Sopenharmony_ci P: Pattern, 810cdb3e2c8Sopenharmony_ci { 811cdb3e2c8Sopenharmony_ci self.trim_end_matches_raw(&pat.__encode()) 812cdb3e2c8Sopenharmony_ci } 813cdb3e2c8Sopenharmony_ci 814cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::trim_matches`]. 815cdb3e2c8Sopenharmony_ci /// 816cdb3e2c8Sopenharmony_ci /// # Examples 817cdb3e2c8Sopenharmony_ci /// 818cdb3e2c8Sopenharmony_ci /// ``` 819cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 820cdb3e2c8Sopenharmony_ci /// 821cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("111foo1bar111"); 822cdb3e2c8Sopenharmony_ci /// assert_eq!("foo1bar", raw.trim_matches("1")); 823cdb3e2c8Sopenharmony_ci /// assert_eq!("111foo1bar111", raw.trim_matches("o")); 824cdb3e2c8Sopenharmony_ci /// ``` 825cdb3e2c8Sopenharmony_ci #[inline] 826cdb3e2c8Sopenharmony_ci #[must_use] 827cdb3e2c8Sopenharmony_ci pub fn trim_matches<P>(&self, pat: P) -> &Self 828cdb3e2c8Sopenharmony_ci where 829cdb3e2c8Sopenharmony_ci P: Pattern, 830cdb3e2c8Sopenharmony_ci { 831cdb3e2c8Sopenharmony_ci let pat = pat.__encode(); 832cdb3e2c8Sopenharmony_ci self.trim_start_matches_raw(&pat).trim_end_matches_raw(&pat) 833cdb3e2c8Sopenharmony_ci } 834cdb3e2c8Sopenharmony_ci 835cdb3e2c8Sopenharmony_ci fn trim_start_matches_raw<P>(&self, pat: &P) -> &Self 836cdb3e2c8Sopenharmony_ci where 837cdb3e2c8Sopenharmony_ci P: EncodedPattern, 838cdb3e2c8Sopenharmony_ci { 839cdb3e2c8Sopenharmony_ci self.trim_matches_raw_with(pat, <[_]>::strip_prefix) 840cdb3e2c8Sopenharmony_ci } 841cdb3e2c8Sopenharmony_ci 842cdb3e2c8Sopenharmony_ci /// Equivalent to [`str::trim_start_matches`]. 843cdb3e2c8Sopenharmony_ci /// 844cdb3e2c8Sopenharmony_ci /// # Examples 845cdb3e2c8Sopenharmony_ci /// 846cdb3e2c8Sopenharmony_ci /// ``` 847cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 848cdb3e2c8Sopenharmony_ci /// 849cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::from_str("111foo1bar111"); 850cdb3e2c8Sopenharmony_ci /// assert_eq!("foo1bar111", raw.trim_start_matches("1")); 851cdb3e2c8Sopenharmony_ci /// assert_eq!("111foo1bar111", raw.trim_start_matches("o")); 852cdb3e2c8Sopenharmony_ci /// ``` 853cdb3e2c8Sopenharmony_ci #[inline] 854cdb3e2c8Sopenharmony_ci #[must_use] 855cdb3e2c8Sopenharmony_ci pub fn trim_start_matches<P>(&self, pat: P) -> &Self 856cdb3e2c8Sopenharmony_ci where 857cdb3e2c8Sopenharmony_ci P: Pattern, 858cdb3e2c8Sopenharmony_ci { 859cdb3e2c8Sopenharmony_ci self.trim_start_matches_raw(&pat.__encode()) 860cdb3e2c8Sopenharmony_ci } 861cdb3e2c8Sopenharmony_ci} 862cdb3e2c8Sopenharmony_ci 863cdb3e2c8Sopenharmony_ciimpl AsRef<Self> for RawOsStr { 864cdb3e2c8Sopenharmony_ci #[inline] 865cdb3e2c8Sopenharmony_ci fn as_ref(&self) -> &Self { 866cdb3e2c8Sopenharmony_ci self 867cdb3e2c8Sopenharmony_ci } 868cdb3e2c8Sopenharmony_ci} 869cdb3e2c8Sopenharmony_ci 870cdb3e2c8Sopenharmony_ciimpl AsRef<RawOsStr> for str { 871cdb3e2c8Sopenharmony_ci #[inline] 872cdb3e2c8Sopenharmony_ci fn as_ref(&self) -> &RawOsStr { 873cdb3e2c8Sopenharmony_ci RawOsStr::from_str(self) 874cdb3e2c8Sopenharmony_ci } 875cdb3e2c8Sopenharmony_ci} 876cdb3e2c8Sopenharmony_ci 877cdb3e2c8Sopenharmony_ciimpl AsRef<RawOsStr> for String { 878cdb3e2c8Sopenharmony_ci #[inline] 879cdb3e2c8Sopenharmony_ci fn as_ref(&self) -> &RawOsStr { 880cdb3e2c8Sopenharmony_ci (**self).as_ref() 881cdb3e2c8Sopenharmony_ci } 882cdb3e2c8Sopenharmony_ci} 883cdb3e2c8Sopenharmony_ci 884cdb3e2c8Sopenharmony_ciimpl Default for &RawOsStr { 885cdb3e2c8Sopenharmony_ci #[inline] 886cdb3e2c8Sopenharmony_ci fn default() -> Self { 887cdb3e2c8Sopenharmony_ci RawOsStr::from_str("") 888cdb3e2c8Sopenharmony_ci } 889cdb3e2c8Sopenharmony_ci} 890cdb3e2c8Sopenharmony_ci 891cdb3e2c8Sopenharmony_ciimpl<'a> From<&'a RawOsStr> for Cow<'a, RawOsStr> { 892cdb3e2c8Sopenharmony_ci #[inline] 893cdb3e2c8Sopenharmony_ci fn from(value: &'a RawOsStr) -> Self { 894cdb3e2c8Sopenharmony_ci Cow::Borrowed(value) 895cdb3e2c8Sopenharmony_ci } 896cdb3e2c8Sopenharmony_ci} 897cdb3e2c8Sopenharmony_ci 898cdb3e2c8Sopenharmony_ciimpl From<Box<str>> for Box<RawOsStr> { 899cdb3e2c8Sopenharmony_ci #[inline] 900cdb3e2c8Sopenharmony_ci fn from(value: Box<str>) -> Self { 901cdb3e2c8Sopenharmony_ci value.into_boxed_bytes().transmute_box() 902cdb3e2c8Sopenharmony_ci } 903cdb3e2c8Sopenharmony_ci} 904cdb3e2c8Sopenharmony_ci 905cdb3e2c8Sopenharmony_ciimpl ToOwned for RawOsStr { 906cdb3e2c8Sopenharmony_ci type Owned = RawOsString; 907cdb3e2c8Sopenharmony_ci 908cdb3e2c8Sopenharmony_ci #[inline] 909cdb3e2c8Sopenharmony_ci fn to_owned(&self) -> Self::Owned { 910cdb3e2c8Sopenharmony_ci RawOsString(self.0.to_owned()) 911cdb3e2c8Sopenharmony_ci } 912cdb3e2c8Sopenharmony_ci} 913cdb3e2c8Sopenharmony_ci 914cdb3e2c8Sopenharmony_ci/// Extensions to [`Cow<RawOsStr>`] for additional conversions. 915cdb3e2c8Sopenharmony_ci/// 916cdb3e2c8Sopenharmony_ci/// [`Cow<RawOsStr>`]: Cow 917cdb3e2c8Sopenharmony_ci#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "raw_os_str")))] 918cdb3e2c8Sopenharmony_cipub trait RawOsStrCow<'a>: private::Sealed { 919cdb3e2c8Sopenharmony_ci /// Converts this representation back to a platform-native string. 920cdb3e2c8Sopenharmony_ci /// 921cdb3e2c8Sopenharmony_ci /// # Examples 922cdb3e2c8Sopenharmony_ci /// 923cdb3e2c8Sopenharmony_ci /// ``` 924cdb3e2c8Sopenharmony_ci /// use std::env; 925cdb3e2c8Sopenharmony_ci /// # use std::io; 926cdb3e2c8Sopenharmony_ci /// 927cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 928cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStrCow; 929cdb3e2c8Sopenharmony_ci /// 930cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 931cdb3e2c8Sopenharmony_ci /// let raw = RawOsStr::new(&os_string); 932cdb3e2c8Sopenharmony_ci /// assert_eq!(os_string, raw.into_os_str()); 933cdb3e2c8Sopenharmony_ci /// # 934cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 935cdb3e2c8Sopenharmony_ci /// ``` 936cdb3e2c8Sopenharmony_ci #[must_use] 937cdb3e2c8Sopenharmony_ci fn into_os_str(self) -> Cow<'a, OsStr>; 938cdb3e2c8Sopenharmony_ci 939cdb3e2c8Sopenharmony_ci /// Returns the byte string stored by this container. 940cdb3e2c8Sopenharmony_ci /// 941cdb3e2c8Sopenharmony_ci /// The returned string will use an [unspecified encoding]. 942cdb3e2c8Sopenharmony_ci /// 943cdb3e2c8Sopenharmony_ci /// # Examples 944cdb3e2c8Sopenharmony_ci /// 945cdb3e2c8Sopenharmony_ci /// ``` 946cdb3e2c8Sopenharmony_ci /// use std::borrow::Cow; 947cdb3e2c8Sopenharmony_ci /// 948cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStr; 949cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsStrCow; 950cdb3e2c8Sopenharmony_ci /// 951cdb3e2c8Sopenharmony_ci /// let string = "foobar"; 952cdb3e2c8Sopenharmony_ci /// let raw = Cow::Borrowed(RawOsStr::from_str(string)); 953cdb3e2c8Sopenharmony_ci /// assert_eq!(string.as_bytes(), &*raw.into_raw_bytes()); 954cdb3e2c8Sopenharmony_ci /// ``` 955cdb3e2c8Sopenharmony_ci /// 956cdb3e2c8Sopenharmony_ci /// [unspecified encoding]: super#encoding 957cdb3e2c8Sopenharmony_ci #[must_use] 958cdb3e2c8Sopenharmony_ci fn into_raw_bytes(self) -> Cow<'a, [u8]>; 959cdb3e2c8Sopenharmony_ci} 960cdb3e2c8Sopenharmony_ci 961cdb3e2c8Sopenharmony_ciimpl<'a> RawOsStrCow<'a> for Cow<'a, RawOsStr> { 962cdb3e2c8Sopenharmony_ci #[inline] 963cdb3e2c8Sopenharmony_ci fn into_os_str(self) -> Cow<'a, OsStr> { 964cdb3e2c8Sopenharmony_ci match self { 965cdb3e2c8Sopenharmony_ci Cow::Borrowed(string) => string.to_os_str(), 966cdb3e2c8Sopenharmony_ci Cow::Owned(string) => Cow::Owned(string.into_os_string()), 967cdb3e2c8Sopenharmony_ci } 968cdb3e2c8Sopenharmony_ci } 969cdb3e2c8Sopenharmony_ci 970cdb3e2c8Sopenharmony_ci #[inline] 971cdb3e2c8Sopenharmony_ci fn into_raw_bytes(self) -> Cow<'a, [u8]> { 972cdb3e2c8Sopenharmony_ci match self { 973cdb3e2c8Sopenharmony_ci Cow::Borrowed(string) => Cow::Borrowed(&string.0), 974cdb3e2c8Sopenharmony_ci Cow::Owned(string) => Cow::Owned(string.0), 975cdb3e2c8Sopenharmony_ci } 976cdb3e2c8Sopenharmony_ci } 977cdb3e2c8Sopenharmony_ci} 978cdb3e2c8Sopenharmony_ci 979cdb3e2c8Sopenharmony_ci/// A container for owned byte strings converted by this crate. 980cdb3e2c8Sopenharmony_ci/// 981cdb3e2c8Sopenharmony_ci/// For more information, see [`RawOsStr`]. 982cdb3e2c8Sopenharmony_ci#[derive(Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] 983cdb3e2c8Sopenharmony_ci#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "raw_os_str")))] 984cdb3e2c8Sopenharmony_cipub struct RawOsString(Vec<u8>); 985cdb3e2c8Sopenharmony_ci 986cdb3e2c8Sopenharmony_ciimpl RawOsString { 987cdb3e2c8Sopenharmony_ci /// Converts a platform-native string into a representation that can be 988cdb3e2c8Sopenharmony_ci /// more easily manipulated. 989cdb3e2c8Sopenharmony_ci /// 990cdb3e2c8Sopenharmony_ci /// For more information, see [`RawOsStr::new`]. 991cdb3e2c8Sopenharmony_ci /// 992cdb3e2c8Sopenharmony_ci /// # Examples 993cdb3e2c8Sopenharmony_ci /// 994cdb3e2c8Sopenharmony_ci /// ``` 995cdb3e2c8Sopenharmony_ci /// use std::env; 996cdb3e2c8Sopenharmony_ci /// # use std::io; 997cdb3e2c8Sopenharmony_ci /// 998cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 999cdb3e2c8Sopenharmony_ci /// 1000cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 1001cdb3e2c8Sopenharmony_ci /// println!("{:?}", RawOsString::new(os_string)); 1002cdb3e2c8Sopenharmony_ci /// # 1003cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 1004cdb3e2c8Sopenharmony_ci /// ``` 1005cdb3e2c8Sopenharmony_ci #[inline] 1006cdb3e2c8Sopenharmony_ci #[must_use] 1007cdb3e2c8Sopenharmony_ci pub fn new(string: OsString) -> Self { 1008cdb3e2c8Sopenharmony_ci Self(imp::os_string_into_vec(string)) 1009cdb3e2c8Sopenharmony_ci } 1010cdb3e2c8Sopenharmony_ci 1011cdb3e2c8Sopenharmony_ci /// Wraps a string, without copying or encoding conversion. 1012cdb3e2c8Sopenharmony_ci /// 1013cdb3e2c8Sopenharmony_ci /// This method is much more efficient than [`RawOsString::new`], since the 1014cdb3e2c8Sopenharmony_ci /// [encoding] used by this crate is compatible with UTF-8. 1015cdb3e2c8Sopenharmony_ci /// 1016cdb3e2c8Sopenharmony_ci /// # Examples 1017cdb3e2c8Sopenharmony_ci /// 1018cdb3e2c8Sopenharmony_ci /// ``` 1019cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1020cdb3e2c8Sopenharmony_ci /// 1021cdb3e2c8Sopenharmony_ci /// let string = "foobar".to_owned(); 1022cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::from_string(string.clone()); 1023cdb3e2c8Sopenharmony_ci /// assert_eq!(string, raw); 1024cdb3e2c8Sopenharmony_ci /// ``` 1025cdb3e2c8Sopenharmony_ci /// 1026cdb3e2c8Sopenharmony_ci /// [encoding]: super#encoding 1027cdb3e2c8Sopenharmony_ci #[inline] 1028cdb3e2c8Sopenharmony_ci #[must_use] 1029cdb3e2c8Sopenharmony_ci pub fn from_string(string: String) -> Self { 1030cdb3e2c8Sopenharmony_ci Self(string.into_bytes()) 1031cdb3e2c8Sopenharmony_ci } 1032cdb3e2c8Sopenharmony_ci 1033cdb3e2c8Sopenharmony_ci /// Wraps a byte string, without copying or encoding conversion. 1034cdb3e2c8Sopenharmony_ci /// 1035cdb3e2c8Sopenharmony_ci /// # Panics 1036cdb3e2c8Sopenharmony_ci /// 1037cdb3e2c8Sopenharmony_ci /// Panics if the string is not valid for the [unspecified encoding] used 1038cdb3e2c8Sopenharmony_ci /// by this crate. 1039cdb3e2c8Sopenharmony_ci /// 1040cdb3e2c8Sopenharmony_ci /// # Examples 1041cdb3e2c8Sopenharmony_ci /// 1042cdb3e2c8Sopenharmony_ci /// ``` 1043cdb3e2c8Sopenharmony_ci /// use std::env; 1044cdb3e2c8Sopenharmony_ci /// # use std::io; 1045cdb3e2c8Sopenharmony_ci /// 1046cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1047cdb3e2c8Sopenharmony_ci /// 1048cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 1049cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::new(os_string); 1050cdb3e2c8Sopenharmony_ci /// let raw_bytes = raw.clone().into_raw_vec(); 1051cdb3e2c8Sopenharmony_ci /// assert_eq!(raw, RawOsString::assert_from_raw_vec(raw_bytes)); 1052cdb3e2c8Sopenharmony_ci /// # 1053cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 1054cdb3e2c8Sopenharmony_ci /// ``` 1055cdb3e2c8Sopenharmony_ci /// 1056cdb3e2c8Sopenharmony_ci /// [unspecified encoding]: super#encoding 1057cdb3e2c8Sopenharmony_ci #[inline] 1058cdb3e2c8Sopenharmony_ci #[must_use = "method should not be used for validation"] 1059cdb3e2c8Sopenharmony_ci #[track_caller] 1060cdb3e2c8Sopenharmony_ci pub fn assert_from_raw_vec(string: Vec<u8>) -> Self { 1061cdb3e2c8Sopenharmony_ci expect_encoded!(raw::validate_bytes(&string)); 1062cdb3e2c8Sopenharmony_ci 1063cdb3e2c8Sopenharmony_ci Self(string) 1064cdb3e2c8Sopenharmony_ci } 1065cdb3e2c8Sopenharmony_ci 1066cdb3e2c8Sopenharmony_ci if_checked_conversions! { 1067cdb3e2c8Sopenharmony_ci /// Wraps a byte string, without copying or encoding conversion. 1068cdb3e2c8Sopenharmony_ci /// 1069cdb3e2c8Sopenharmony_ci /// [`assert_from_raw_vec`] should almost always be used instead. For 1070cdb3e2c8Sopenharmony_ci /// more information, see [`EncodingError`]. 1071cdb3e2c8Sopenharmony_ci /// 1072cdb3e2c8Sopenharmony_ci /// # Errors 1073cdb3e2c8Sopenharmony_ci /// 1074cdb3e2c8Sopenharmony_ci /// See documentation for [`EncodingError`]. 1075cdb3e2c8Sopenharmony_ci /// 1076cdb3e2c8Sopenharmony_ci /// # Examples 1077cdb3e2c8Sopenharmony_ci /// 1078cdb3e2c8Sopenharmony_ci /// ``` 1079cdb3e2c8Sopenharmony_ci /// use std::env; 1080cdb3e2c8Sopenharmony_ci /// # use std::io; 1081cdb3e2c8Sopenharmony_ci /// 1082cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1083cdb3e2c8Sopenharmony_ci /// 1084cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 1085cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::new(os_string); 1086cdb3e2c8Sopenharmony_ci /// let raw_clone = raw.clone(); 1087cdb3e2c8Sopenharmony_ci /// assert_eq!(Ok(raw), RawOsString::from_raw_vec(raw_clone.into_raw_vec())); 1088cdb3e2c8Sopenharmony_ci /// # 1089cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 1090cdb3e2c8Sopenharmony_ci /// ``` 1091cdb3e2c8Sopenharmony_ci /// 1092cdb3e2c8Sopenharmony_ci /// [`assert_from_raw_vec`]: Self::assert_from_raw_vec 1093cdb3e2c8Sopenharmony_ci #[cfg_attr( 1094cdb3e2c8Sopenharmony_ci os_str_bytes_docs_rs, 1095cdb3e2c8Sopenharmony_ci doc(cfg(feature = "checked_conversions")) 1096cdb3e2c8Sopenharmony_ci )] 1097cdb3e2c8Sopenharmony_ci #[inline] 1098cdb3e2c8Sopenharmony_ci pub fn from_raw_vec(string: Vec<u8>) -> Result<Self> { 1099cdb3e2c8Sopenharmony_ci raw::validate_bytes(&string) 1100cdb3e2c8Sopenharmony_ci .map(|()| Self(string)) 1101cdb3e2c8Sopenharmony_ci .map_err(EncodingError) 1102cdb3e2c8Sopenharmony_ci } 1103cdb3e2c8Sopenharmony_ci } 1104cdb3e2c8Sopenharmony_ci 1105cdb3e2c8Sopenharmony_ci /// Wraps a byte string, without copying or encoding conversion. 1106cdb3e2c8Sopenharmony_ci /// 1107cdb3e2c8Sopenharmony_ci /// # Safety 1108cdb3e2c8Sopenharmony_ci /// 1109cdb3e2c8Sopenharmony_ci /// The string must be valid for the [unspecified encoding] used by this 1110cdb3e2c8Sopenharmony_ci /// crate. 1111cdb3e2c8Sopenharmony_ci /// 1112cdb3e2c8Sopenharmony_ci /// # Examples 1113cdb3e2c8Sopenharmony_ci /// 1114cdb3e2c8Sopenharmony_ci /// ``` 1115cdb3e2c8Sopenharmony_ci /// use std::env; 1116cdb3e2c8Sopenharmony_ci /// # use std::io; 1117cdb3e2c8Sopenharmony_ci /// 1118cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1119cdb3e2c8Sopenharmony_ci /// 1120cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 1121cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::new(os_string); 1122cdb3e2c8Sopenharmony_ci /// let raw_bytes = raw.clone().into_raw_vec(); 1123cdb3e2c8Sopenharmony_ci /// assert_eq!(raw, unsafe { 1124cdb3e2c8Sopenharmony_ci /// RawOsString::from_raw_vec_unchecked(raw_bytes) 1125cdb3e2c8Sopenharmony_ci /// }); 1126cdb3e2c8Sopenharmony_ci /// # 1127cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 1128cdb3e2c8Sopenharmony_ci /// ``` 1129cdb3e2c8Sopenharmony_ci /// 1130cdb3e2c8Sopenharmony_ci /// [unspecified encoding]: super#encoding 1131cdb3e2c8Sopenharmony_ci #[inline] 1132cdb3e2c8Sopenharmony_ci #[must_use] 1133cdb3e2c8Sopenharmony_ci #[track_caller] 1134cdb3e2c8Sopenharmony_ci pub unsafe fn from_raw_vec_unchecked(string: Vec<u8>) -> Self { 1135cdb3e2c8Sopenharmony_ci if cfg!(debug_assertions) { 1136cdb3e2c8Sopenharmony_ci expect_encoded!(raw::validate_bytes(&string)); 1137cdb3e2c8Sopenharmony_ci } 1138cdb3e2c8Sopenharmony_ci 1139cdb3e2c8Sopenharmony_ci Self(string) 1140cdb3e2c8Sopenharmony_ci } 1141cdb3e2c8Sopenharmony_ci 1142cdb3e2c8Sopenharmony_ci /// Equivalent to [`String::clear`]. 1143cdb3e2c8Sopenharmony_ci /// 1144cdb3e2c8Sopenharmony_ci /// # Examples 1145cdb3e2c8Sopenharmony_ci /// 1146cdb3e2c8Sopenharmony_ci /// ``` 1147cdb3e2c8Sopenharmony_ci /// use std::env; 1148cdb3e2c8Sopenharmony_ci /// # use std::io; 1149cdb3e2c8Sopenharmony_ci /// 1150cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1151cdb3e2c8Sopenharmony_ci /// 1152cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 1153cdb3e2c8Sopenharmony_ci /// let mut raw = RawOsString::new(os_string); 1154cdb3e2c8Sopenharmony_ci /// raw.clear(); 1155cdb3e2c8Sopenharmony_ci /// assert!(raw.is_empty()); 1156cdb3e2c8Sopenharmony_ci /// # 1157cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 1158cdb3e2c8Sopenharmony_ci /// ``` 1159cdb3e2c8Sopenharmony_ci #[inline] 1160cdb3e2c8Sopenharmony_ci pub fn clear(&mut self) { 1161cdb3e2c8Sopenharmony_ci self.0.clear(); 1162cdb3e2c8Sopenharmony_ci } 1163cdb3e2c8Sopenharmony_ci 1164cdb3e2c8Sopenharmony_ci /// Equivalent to [`String::into_boxed_str`]. 1165cdb3e2c8Sopenharmony_ci /// 1166cdb3e2c8Sopenharmony_ci /// # Examples 1167cdb3e2c8Sopenharmony_ci /// 1168cdb3e2c8Sopenharmony_ci /// ``` 1169cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1170cdb3e2c8Sopenharmony_ci /// 1171cdb3e2c8Sopenharmony_ci /// let string = "foobar".to_owned(); 1172cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::from_string(string.clone()); 1173cdb3e2c8Sopenharmony_ci /// assert_eq!(string, *raw.into_box()); 1174cdb3e2c8Sopenharmony_ci /// ``` 1175cdb3e2c8Sopenharmony_ci #[inline] 1176cdb3e2c8Sopenharmony_ci #[must_use] 1177cdb3e2c8Sopenharmony_ci pub fn into_box(self) -> Box<RawOsStr> { 1178cdb3e2c8Sopenharmony_ci self.0.into_boxed_slice().transmute_box() 1179cdb3e2c8Sopenharmony_ci } 1180cdb3e2c8Sopenharmony_ci 1181cdb3e2c8Sopenharmony_ci /// Converts this representation back to a platform-native string. 1182cdb3e2c8Sopenharmony_ci /// 1183cdb3e2c8Sopenharmony_ci /// # Examples 1184cdb3e2c8Sopenharmony_ci /// 1185cdb3e2c8Sopenharmony_ci /// ``` 1186cdb3e2c8Sopenharmony_ci /// use std::env; 1187cdb3e2c8Sopenharmony_ci /// # use std::io; 1188cdb3e2c8Sopenharmony_ci /// 1189cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1190cdb3e2c8Sopenharmony_ci /// 1191cdb3e2c8Sopenharmony_ci /// let os_string = env::current_exe()?.into_os_string(); 1192cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::new(os_string.clone()); 1193cdb3e2c8Sopenharmony_ci /// assert_eq!(os_string, raw.into_os_string()); 1194cdb3e2c8Sopenharmony_ci /// # 1195cdb3e2c8Sopenharmony_ci /// # Ok::<_, io::Error>(()) 1196cdb3e2c8Sopenharmony_ci /// ``` 1197cdb3e2c8Sopenharmony_ci #[inline] 1198cdb3e2c8Sopenharmony_ci #[must_use] 1199cdb3e2c8Sopenharmony_ci pub fn into_os_string(self) -> OsString { 1200cdb3e2c8Sopenharmony_ci expect_encoded!(imp::os_string_from_vec(self.0)) 1201cdb3e2c8Sopenharmony_ci } 1202cdb3e2c8Sopenharmony_ci 1203cdb3e2c8Sopenharmony_ci /// Returns the byte string stored by this container. 1204cdb3e2c8Sopenharmony_ci /// 1205cdb3e2c8Sopenharmony_ci /// The returned string will use an [unspecified encoding]. 1206cdb3e2c8Sopenharmony_ci /// 1207cdb3e2c8Sopenharmony_ci /// # Examples 1208cdb3e2c8Sopenharmony_ci /// 1209cdb3e2c8Sopenharmony_ci /// ``` 1210cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1211cdb3e2c8Sopenharmony_ci /// 1212cdb3e2c8Sopenharmony_ci /// let string = "foobar".to_owned(); 1213cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::from_string(string.clone()); 1214cdb3e2c8Sopenharmony_ci /// assert_eq!(string.into_bytes(), raw.into_raw_vec()); 1215cdb3e2c8Sopenharmony_ci /// ``` 1216cdb3e2c8Sopenharmony_ci /// 1217cdb3e2c8Sopenharmony_ci /// [unspecified encoding]: super#encoding 1218cdb3e2c8Sopenharmony_ci #[inline] 1219cdb3e2c8Sopenharmony_ci #[must_use] 1220cdb3e2c8Sopenharmony_ci pub fn into_raw_vec(self) -> Vec<u8> { 1221cdb3e2c8Sopenharmony_ci self.0 1222cdb3e2c8Sopenharmony_ci } 1223cdb3e2c8Sopenharmony_ci 1224cdb3e2c8Sopenharmony_ci /// Equivalent to [`OsString::into_string`]. 1225cdb3e2c8Sopenharmony_ci /// 1226cdb3e2c8Sopenharmony_ci /// # Examples 1227cdb3e2c8Sopenharmony_ci /// 1228cdb3e2c8Sopenharmony_ci /// ``` 1229cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1230cdb3e2c8Sopenharmony_ci /// 1231cdb3e2c8Sopenharmony_ci /// let string = "foobar".to_owned(); 1232cdb3e2c8Sopenharmony_ci /// let raw = RawOsString::from_string(string.clone()); 1233cdb3e2c8Sopenharmony_ci /// assert_eq!(Ok(string), raw.into_string()); 1234cdb3e2c8Sopenharmony_ci /// ``` 1235cdb3e2c8Sopenharmony_ci #[inline] 1236cdb3e2c8Sopenharmony_ci pub fn into_string(self) -> result::Result<String, Self> { 1237cdb3e2c8Sopenharmony_ci String::from_utf8(self.0).map_err(|x| Self(x.into_bytes())) 1238cdb3e2c8Sopenharmony_ci } 1239cdb3e2c8Sopenharmony_ci 1240cdb3e2c8Sopenharmony_ci /// Equivalent to [`String::shrink_to_fit`]. 1241cdb3e2c8Sopenharmony_ci /// 1242cdb3e2c8Sopenharmony_ci /// # Examples 1243cdb3e2c8Sopenharmony_ci /// 1244cdb3e2c8Sopenharmony_ci /// ``` 1245cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1246cdb3e2c8Sopenharmony_ci /// 1247cdb3e2c8Sopenharmony_ci /// let string = "foobar".to_owned(); 1248cdb3e2c8Sopenharmony_ci /// let mut raw = RawOsString::from_string(string.clone()); 1249cdb3e2c8Sopenharmony_ci /// raw.shrink_to_fit(); 1250cdb3e2c8Sopenharmony_ci /// assert_eq!(string, raw); 1251cdb3e2c8Sopenharmony_ci /// ``` 1252cdb3e2c8Sopenharmony_ci #[inline] 1253cdb3e2c8Sopenharmony_ci pub fn shrink_to_fit(&mut self) { 1254cdb3e2c8Sopenharmony_ci self.0.shrink_to_fit(); 1255cdb3e2c8Sopenharmony_ci } 1256cdb3e2c8Sopenharmony_ci 1257cdb3e2c8Sopenharmony_ci /// Equivalent to [`String::split_off`]. 1258cdb3e2c8Sopenharmony_ci /// 1259cdb3e2c8Sopenharmony_ci /// # Panics 1260cdb3e2c8Sopenharmony_ci /// 1261cdb3e2c8Sopenharmony_ci /// Panics if the index is not a [valid boundary]. 1262cdb3e2c8Sopenharmony_ci /// 1263cdb3e2c8Sopenharmony_ci /// # Examples 1264cdb3e2c8Sopenharmony_ci /// 1265cdb3e2c8Sopenharmony_ci /// ``` 1266cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1267cdb3e2c8Sopenharmony_ci /// 1268cdb3e2c8Sopenharmony_ci /// let mut raw = RawOsString::from_string("foobar".to_owned()); 1269cdb3e2c8Sopenharmony_ci /// assert_eq!("bar", raw.split_off(3)); 1270cdb3e2c8Sopenharmony_ci /// assert_eq!("foo", raw); 1271cdb3e2c8Sopenharmony_ci /// ``` 1272cdb3e2c8Sopenharmony_ci /// 1273cdb3e2c8Sopenharmony_ci /// [valid boundary]: RawOsStr#indices 1274cdb3e2c8Sopenharmony_ci #[inline] 1275cdb3e2c8Sopenharmony_ci #[must_use] 1276cdb3e2c8Sopenharmony_ci #[track_caller] 1277cdb3e2c8Sopenharmony_ci pub fn split_off(&mut self, at: usize) -> Self { 1278cdb3e2c8Sopenharmony_ci self.check_bound(at); 1279cdb3e2c8Sopenharmony_ci 1280cdb3e2c8Sopenharmony_ci Self(self.0.split_off(at)) 1281cdb3e2c8Sopenharmony_ci } 1282cdb3e2c8Sopenharmony_ci 1283cdb3e2c8Sopenharmony_ci /// Equivalent to [`String::truncate`]. 1284cdb3e2c8Sopenharmony_ci /// 1285cdb3e2c8Sopenharmony_ci /// # Panics 1286cdb3e2c8Sopenharmony_ci /// 1287cdb3e2c8Sopenharmony_ci /// Panics if the index is not a [valid boundary]. 1288cdb3e2c8Sopenharmony_ci /// 1289cdb3e2c8Sopenharmony_ci /// # Examples 1290cdb3e2c8Sopenharmony_ci /// 1291cdb3e2c8Sopenharmony_ci /// ``` 1292cdb3e2c8Sopenharmony_ci /// use os_str_bytes::RawOsString; 1293cdb3e2c8Sopenharmony_ci /// 1294cdb3e2c8Sopenharmony_ci /// let mut raw = RawOsString::from_string("foobar".to_owned()); 1295cdb3e2c8Sopenharmony_ci /// raw.truncate(3); 1296cdb3e2c8Sopenharmony_ci /// assert_eq!("foo", raw); 1297cdb3e2c8Sopenharmony_ci /// ``` 1298cdb3e2c8Sopenharmony_ci /// 1299cdb3e2c8Sopenharmony_ci /// [valid boundary]: RawOsStr#indices 1300cdb3e2c8Sopenharmony_ci #[inline] 1301cdb3e2c8Sopenharmony_ci #[track_caller] 1302cdb3e2c8Sopenharmony_ci pub fn truncate(&mut self, new_len: usize) { 1303cdb3e2c8Sopenharmony_ci self.check_bound(new_len); 1304cdb3e2c8Sopenharmony_ci 1305cdb3e2c8Sopenharmony_ci self.0.truncate(new_len); 1306cdb3e2c8Sopenharmony_ci } 1307cdb3e2c8Sopenharmony_ci} 1308cdb3e2c8Sopenharmony_ci 1309cdb3e2c8Sopenharmony_ciimpl AsRef<RawOsStr> for RawOsString { 1310cdb3e2c8Sopenharmony_ci #[inline] 1311cdb3e2c8Sopenharmony_ci fn as_ref(&self) -> &RawOsStr { 1312cdb3e2c8Sopenharmony_ci self 1313cdb3e2c8Sopenharmony_ci } 1314cdb3e2c8Sopenharmony_ci} 1315cdb3e2c8Sopenharmony_ci 1316cdb3e2c8Sopenharmony_ciimpl Borrow<RawOsStr> for RawOsString { 1317cdb3e2c8Sopenharmony_ci #[inline] 1318cdb3e2c8Sopenharmony_ci fn borrow(&self) -> &RawOsStr { 1319cdb3e2c8Sopenharmony_ci self 1320cdb3e2c8Sopenharmony_ci } 1321cdb3e2c8Sopenharmony_ci} 1322cdb3e2c8Sopenharmony_ci 1323cdb3e2c8Sopenharmony_ciimpl Deref for RawOsString { 1324cdb3e2c8Sopenharmony_ci type Target = RawOsStr; 1325cdb3e2c8Sopenharmony_ci 1326cdb3e2c8Sopenharmony_ci #[inline] 1327cdb3e2c8Sopenharmony_ci fn deref(&self) -> &Self::Target { 1328cdb3e2c8Sopenharmony_ci RawOsStr::from_inner(&self.0) 1329cdb3e2c8Sopenharmony_ci } 1330cdb3e2c8Sopenharmony_ci} 1331cdb3e2c8Sopenharmony_ci 1332cdb3e2c8Sopenharmony_ciimpl From<RawOsString> for Box<RawOsStr> { 1333cdb3e2c8Sopenharmony_ci #[inline] 1334cdb3e2c8Sopenharmony_ci fn from(value: RawOsString) -> Self { 1335cdb3e2c8Sopenharmony_ci value.into_box() 1336cdb3e2c8Sopenharmony_ci } 1337cdb3e2c8Sopenharmony_ci} 1338cdb3e2c8Sopenharmony_ci 1339cdb3e2c8Sopenharmony_ciimpl From<Box<RawOsStr>> for RawOsString { 1340cdb3e2c8Sopenharmony_ci #[inline] 1341cdb3e2c8Sopenharmony_ci fn from(value: Box<RawOsStr>) -> Self { 1342cdb3e2c8Sopenharmony_ci Self(value.transmute_box::<[_]>().into_vec()) 1343cdb3e2c8Sopenharmony_ci } 1344cdb3e2c8Sopenharmony_ci} 1345cdb3e2c8Sopenharmony_ci 1346cdb3e2c8Sopenharmony_ciimpl From<RawOsString> for Cow<'_, RawOsStr> { 1347cdb3e2c8Sopenharmony_ci #[inline] 1348cdb3e2c8Sopenharmony_ci fn from(value: RawOsString) -> Self { 1349cdb3e2c8Sopenharmony_ci Cow::Owned(value) 1350cdb3e2c8Sopenharmony_ci } 1351cdb3e2c8Sopenharmony_ci} 1352cdb3e2c8Sopenharmony_ci 1353cdb3e2c8Sopenharmony_ciimpl From<String> for RawOsString { 1354cdb3e2c8Sopenharmony_ci #[inline] 1355cdb3e2c8Sopenharmony_ci fn from(value: String) -> Self { 1356cdb3e2c8Sopenharmony_ci Self::from_string(value) 1357cdb3e2c8Sopenharmony_ci } 1358cdb3e2c8Sopenharmony_ci} 1359cdb3e2c8Sopenharmony_ci 1360cdb3e2c8Sopenharmony_cistruct DebugBuffer<'a>(&'a [u8]); 1361cdb3e2c8Sopenharmony_ci 1362cdb3e2c8Sopenharmony_ciimpl Debug for DebugBuffer<'_> { 1363cdb3e2c8Sopenharmony_ci fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 1364cdb3e2c8Sopenharmony_ci f.write_str("\"")?; 1365cdb3e2c8Sopenharmony_ci 1366cdb3e2c8Sopenharmony_ci let mut string = self.0; 1367cdb3e2c8Sopenharmony_ci let mut invalid_length = 0; 1368cdb3e2c8Sopenharmony_ci while !string.is_empty() { 1369cdb3e2c8Sopenharmony_ci let (invalid, substring) = string.split_at(invalid_length); 1370cdb3e2c8Sopenharmony_ci 1371cdb3e2c8Sopenharmony_ci let valid = match str::from_utf8(substring) { 1372cdb3e2c8Sopenharmony_ci Ok(valid) => { 1373cdb3e2c8Sopenharmony_ci string = &[]; 1374cdb3e2c8Sopenharmony_ci valid 1375cdb3e2c8Sopenharmony_ci } 1376cdb3e2c8Sopenharmony_ci Err(error) => { 1377cdb3e2c8Sopenharmony_ci let (valid, substring) = 1378cdb3e2c8Sopenharmony_ci substring.split_at(error.valid_up_to()); 1379cdb3e2c8Sopenharmony_ci 1380cdb3e2c8Sopenharmony_ci let invalid_char_length = 1381cdb3e2c8Sopenharmony_ci error.error_len().unwrap_or_else(|| substring.len()); 1382cdb3e2c8Sopenharmony_ci if valid.is_empty() { 1383cdb3e2c8Sopenharmony_ci invalid_length += invalid_char_length; 1384cdb3e2c8Sopenharmony_ci continue; 1385cdb3e2c8Sopenharmony_ci } 1386cdb3e2c8Sopenharmony_ci string = substring; 1387cdb3e2c8Sopenharmony_ci invalid_length = invalid_char_length; 1388cdb3e2c8Sopenharmony_ci 1389cdb3e2c8Sopenharmony_ci // SAFETY: This slice was validated to be UTF-8. 1390cdb3e2c8Sopenharmony_ci unsafe { str::from_utf8_unchecked(valid) } 1391cdb3e2c8Sopenharmony_ci } 1392cdb3e2c8Sopenharmony_ci }; 1393cdb3e2c8Sopenharmony_ci 1394cdb3e2c8Sopenharmony_ci raw::debug(invalid, f)?; 1395cdb3e2c8Sopenharmony_ci Display::fmt(&valid.escape_debug(), f)?; 1396cdb3e2c8Sopenharmony_ci } 1397cdb3e2c8Sopenharmony_ci 1398cdb3e2c8Sopenharmony_ci f.write_str("\"") 1399cdb3e2c8Sopenharmony_ci } 1400cdb3e2c8Sopenharmony_ci} 1401cdb3e2c8Sopenharmony_ci 1402cdb3e2c8Sopenharmony_cimacro_rules! r#impl { 1403cdb3e2c8Sopenharmony_ci ( $type:ty ) => { 1404cdb3e2c8Sopenharmony_ci impl Debug for $type { 1405cdb3e2c8Sopenharmony_ci #[inline] 1406cdb3e2c8Sopenharmony_ci fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 1407cdb3e2c8Sopenharmony_ci f.debug_tuple(stringify!($type)) 1408cdb3e2c8Sopenharmony_ci .field(&DebugBuffer(&self.0)) 1409cdb3e2c8Sopenharmony_ci .finish() 1410cdb3e2c8Sopenharmony_ci } 1411cdb3e2c8Sopenharmony_ci } 1412cdb3e2c8Sopenharmony_ci }; 1413cdb3e2c8Sopenharmony_ci} 1414cdb3e2c8Sopenharmony_cir#impl!(RawOsStr); 1415cdb3e2c8Sopenharmony_cir#impl!(RawOsString); 1416cdb3e2c8Sopenharmony_ci 1417cdb3e2c8Sopenharmony_cimacro_rules! r#impl { 1418cdb3e2c8Sopenharmony_ci ( $index_type:ty $(, $index_var:ident , $($bound:expr),+)? ) => { 1419cdb3e2c8Sopenharmony_ci impl Index<$index_type> for RawOsStr { 1420cdb3e2c8Sopenharmony_ci type Output = Self; 1421cdb3e2c8Sopenharmony_ci 1422cdb3e2c8Sopenharmony_ci #[inline] 1423cdb3e2c8Sopenharmony_ci fn index(&self, idx: $index_type) -> &Self::Output { 1424cdb3e2c8Sopenharmony_ci $( 1425cdb3e2c8Sopenharmony_ci let $index_var = &idx; 1426cdb3e2c8Sopenharmony_ci $(self.check_bound($bound);)+ 1427cdb3e2c8Sopenharmony_ci )? 1428cdb3e2c8Sopenharmony_ci 1429cdb3e2c8Sopenharmony_ci Self::from_inner(&self.0[idx]) 1430cdb3e2c8Sopenharmony_ci } 1431cdb3e2c8Sopenharmony_ci } 1432cdb3e2c8Sopenharmony_ci 1433cdb3e2c8Sopenharmony_ci impl Index<$index_type> for RawOsString { 1434cdb3e2c8Sopenharmony_ci type Output = RawOsStr; 1435cdb3e2c8Sopenharmony_ci 1436cdb3e2c8Sopenharmony_ci #[allow(clippy::indexing_slicing)] 1437cdb3e2c8Sopenharmony_ci #[inline] 1438cdb3e2c8Sopenharmony_ci fn index(&self, idx: $index_type) -> &Self::Output { 1439cdb3e2c8Sopenharmony_ci &(**self)[idx] 1440cdb3e2c8Sopenharmony_ci } 1441cdb3e2c8Sopenharmony_ci } 1442cdb3e2c8Sopenharmony_ci }; 1443cdb3e2c8Sopenharmony_ci} 1444cdb3e2c8Sopenharmony_cir#impl!(Range<usize>, x, x.start, x.end); 1445cdb3e2c8Sopenharmony_cir#impl!(RangeFrom<usize>, x, x.start); 1446cdb3e2c8Sopenharmony_cir#impl!(RangeFull); 1447cdb3e2c8Sopenharmony_ci// [usize::MAX] will always be a valid inclusive end index. 1448cdb3e2c8Sopenharmony_ci#[rustfmt::skip] 1449cdb3e2c8Sopenharmony_cir#impl!(RangeInclusive<usize>, x, *x.start(), x.end().wrapping_add(1)); 1450cdb3e2c8Sopenharmony_cir#impl!(RangeTo<usize>, x, x.end); 1451cdb3e2c8Sopenharmony_cir#impl!(RangeToInclusive<usize>, x, x.end.wrapping_add(1)); 1452cdb3e2c8Sopenharmony_ci 1453cdb3e2c8Sopenharmony_cimacro_rules! r#impl { 1454cdb3e2c8Sopenharmony_ci ( $type:ty , $other_type:ty ) => { 1455cdb3e2c8Sopenharmony_ci impl PartialEq<$other_type> for $type { 1456cdb3e2c8Sopenharmony_ci #[inline] 1457cdb3e2c8Sopenharmony_ci fn eq(&self, other: &$other_type) -> bool { 1458cdb3e2c8Sopenharmony_ci let raw: &RawOsStr = self; 1459cdb3e2c8Sopenharmony_ci let other: &RawOsStr = other.as_ref(); 1460cdb3e2c8Sopenharmony_ci raw == other 1461cdb3e2c8Sopenharmony_ci } 1462cdb3e2c8Sopenharmony_ci } 1463cdb3e2c8Sopenharmony_ci 1464cdb3e2c8Sopenharmony_ci impl PartialEq<$type> for $other_type { 1465cdb3e2c8Sopenharmony_ci #[inline] 1466cdb3e2c8Sopenharmony_ci fn eq(&self, other: &$type) -> bool { 1467cdb3e2c8Sopenharmony_ci other == self 1468cdb3e2c8Sopenharmony_ci } 1469cdb3e2c8Sopenharmony_ci } 1470cdb3e2c8Sopenharmony_ci }; 1471cdb3e2c8Sopenharmony_ci} 1472cdb3e2c8Sopenharmony_cir#impl!(RawOsStr, RawOsString); 1473cdb3e2c8Sopenharmony_cir#impl!(&RawOsStr, RawOsString); 1474cdb3e2c8Sopenharmony_cir#impl!(RawOsStr, str); 1475cdb3e2c8Sopenharmony_cir#impl!(RawOsStr, String); 1476cdb3e2c8Sopenharmony_cir#impl!(&RawOsStr, String); 1477cdb3e2c8Sopenharmony_cir#impl!(RawOsString, str); 1478cdb3e2c8Sopenharmony_cir#impl!(RawOsString, &str); 1479cdb3e2c8Sopenharmony_cir#impl!(RawOsString, String); 1480cdb3e2c8Sopenharmony_ci 1481cdb3e2c8Sopenharmony_ci#[cfg(feature = "print_bytes")] 1482cdb3e2c8Sopenharmony_ci#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "print_bytes")))] 1483cdb3e2c8Sopenharmony_cimod print_bytes { 1484cdb3e2c8Sopenharmony_ci use print_bytes::ByteStr; 1485cdb3e2c8Sopenharmony_ci use print_bytes::ToBytes; 1486cdb3e2c8Sopenharmony_ci #[cfg(windows)] 1487cdb3e2c8Sopenharmony_ci use print_bytes::WideStr; 1488cdb3e2c8Sopenharmony_ci 1489cdb3e2c8Sopenharmony_ci #[cfg(windows)] 1490cdb3e2c8Sopenharmony_ci use crate::imp::raw; 1491cdb3e2c8Sopenharmony_ci 1492cdb3e2c8Sopenharmony_ci use super::RawOsStr; 1493cdb3e2c8Sopenharmony_ci use super::RawOsString; 1494cdb3e2c8Sopenharmony_ci 1495cdb3e2c8Sopenharmony_ci impl ToBytes for RawOsStr { 1496cdb3e2c8Sopenharmony_ci #[inline] 1497cdb3e2c8Sopenharmony_ci fn to_bytes(&self) -> ByteStr<'_> { 1498cdb3e2c8Sopenharmony_ci self.0.to_bytes() 1499cdb3e2c8Sopenharmony_ci } 1500cdb3e2c8Sopenharmony_ci 1501cdb3e2c8Sopenharmony_ci #[cfg(windows)] 1502cdb3e2c8Sopenharmony_ci #[inline] 1503cdb3e2c8Sopenharmony_ci fn to_wide(&self) -> Option<WideStr> { 1504cdb3e2c8Sopenharmony_ci Some(WideStr::new(raw::encode_wide_unchecked(&self.0).collect())) 1505cdb3e2c8Sopenharmony_ci } 1506cdb3e2c8Sopenharmony_ci } 1507cdb3e2c8Sopenharmony_ci 1508cdb3e2c8Sopenharmony_ci impl ToBytes for RawOsString { 1509cdb3e2c8Sopenharmony_ci #[inline] 1510cdb3e2c8Sopenharmony_ci fn to_bytes(&self) -> ByteStr<'_> { 1511cdb3e2c8Sopenharmony_ci (**self).to_bytes() 1512cdb3e2c8Sopenharmony_ci } 1513cdb3e2c8Sopenharmony_ci 1514cdb3e2c8Sopenharmony_ci #[cfg(windows)] 1515cdb3e2c8Sopenharmony_ci #[inline] 1516cdb3e2c8Sopenharmony_ci fn to_wide(&self) -> Option<WideStr> { 1517cdb3e2c8Sopenharmony_ci (**self).to_wide() 1518cdb3e2c8Sopenharmony_ci } 1519cdb3e2c8Sopenharmony_ci } 1520cdb3e2c8Sopenharmony_ci} 1521cdb3e2c8Sopenharmony_ci 1522cdb3e2c8Sopenharmony_ci#[cfg(feature = "uniquote")] 1523cdb3e2c8Sopenharmony_ci#[cfg_attr(os_str_bytes_docs_rs, doc(cfg(feature = "uniquote")))] 1524cdb3e2c8Sopenharmony_cimod uniquote { 1525cdb3e2c8Sopenharmony_ci use uniquote::Formatter; 1526cdb3e2c8Sopenharmony_ci use uniquote::Quote; 1527cdb3e2c8Sopenharmony_ci use uniquote::Result; 1528cdb3e2c8Sopenharmony_ci 1529cdb3e2c8Sopenharmony_ci use crate::imp::raw; 1530cdb3e2c8Sopenharmony_ci 1531cdb3e2c8Sopenharmony_ci use super::RawOsStr; 1532cdb3e2c8Sopenharmony_ci use super::RawOsString; 1533cdb3e2c8Sopenharmony_ci 1534cdb3e2c8Sopenharmony_ci impl Quote for RawOsStr { 1535cdb3e2c8Sopenharmony_ci #[inline] 1536cdb3e2c8Sopenharmony_ci fn escape(&self, f: &mut Formatter<'_>) -> Result { 1537cdb3e2c8Sopenharmony_ci raw::uniquote::escape(&self.0, f) 1538cdb3e2c8Sopenharmony_ci } 1539cdb3e2c8Sopenharmony_ci } 1540cdb3e2c8Sopenharmony_ci 1541cdb3e2c8Sopenharmony_ci impl Quote for RawOsString { 1542cdb3e2c8Sopenharmony_ci #[inline] 1543cdb3e2c8Sopenharmony_ci fn escape(&self, f: &mut Formatter<'_>) -> Result { 1544cdb3e2c8Sopenharmony_ci (**self).escape(f) 1545cdb3e2c8Sopenharmony_ci } 1546cdb3e2c8Sopenharmony_ci } 1547cdb3e2c8Sopenharmony_ci} 1548