diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-07-22 11:48:53 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-22 11:48:53 +0200 |
| commit | 0877d11e8dee12839804909171e61ad77ae0656a (patch) | |
| tree | 4e21a2b0734666644c2d6e099190aab7d633ef2d /library/std/src/ffi | |
| parent | 58a4be1dfb696132b129fcb33bee91070e2fdbdb (diff) | |
| parent | ee604fccd9d91b8f4cf9b4cad5bafdf698dd0335 (diff) | |
| download | rust-0877d11e8dee12839804909171e61ad77ae0656a.tar.gz rust-0877d11e8dee12839804909171e61ad77ae0656a.zip | |
Rollup merge of #113442 - epage:osstring, r=cuviper
Allow limited access to `OsString` bytes This extends #109698 to allow no-cost conversion between `Vec<u8>` and `OsString` as suggested in feedback from `os_str_bytes` crate in #111544.
Diffstat (limited to 'library/std/src/ffi')
| -rw-r--r-- | library/std/src/ffi/os_str.rs | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index e7bad9d542c..67e58fd1b86 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -141,6 +141,51 @@ impl OsString { OsString { inner: Buf::from_string(String::new()) } } + /// Converts bytes to an `OsString` without checking that the bytes contains + /// valid [`OsStr`]-encoded data. + /// + /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8. + /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit + /// ASCII. + /// + /// See the [module's toplevel documentation about conversions][conversions] for safe, + /// cross-platform [conversions] from/to native representations. + /// + /// # Safety + /// + /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of + /// validated UTF-8 and bytes from [`OsStr::as_os_str_bytes`] from within the same rust version + /// built for the same target platform. For example, reconstructing an `OsString` from bytes sent + /// over the network or stored in a file will likely violate these safety rules. + /// + /// Due to the encoding being self-synchronizing, the bytes from [`OsStr::as_os_str_bytes`] can be + /// split either immediately before or immediately after any valid non-empty UTF-8 substring. + /// + /// # Example + /// + /// ``` + /// #![feature(os_str_bytes)] + /// + /// use std::ffi::OsStr; + /// + /// let os_str = OsStr::new("Mary had a little lamb"); + /// let bytes = os_str.as_os_str_bytes(); + /// let words = bytes.split(|b| *b == b' '); + /// let words: Vec<&OsStr> = words.map(|word| { + /// // SAFETY: + /// // - Each `word` only contains content that originated from `OsStr::as_os_str_bytes` + /// // - Only split with ASCII whitespace which is a non-empty UTF-8 substring + /// unsafe { OsStr::from_os_str_bytes_unchecked(word) } + /// }).collect(); + /// ``` + /// + /// [conversions]: super#conversions + #[inline] + #[unstable(feature = "os_str_bytes", issue = "111544")] + pub unsafe fn from_os_str_bytes_unchecked(bytes: Vec<u8>) -> Self { + OsString { inner: Buf::from_os_str_bytes_unchecked(bytes) } + } + /// Converts to an [`OsStr`] slice. /// /// # Examples @@ -159,6 +204,26 @@ impl OsString { self } + /// Converts the `OsString` into a byte slice. To convert the byte slice back into an + /// `OsString`, use the [`OsStr::from_os_str_bytes_unchecked`] function. + /// + /// The byte encoding is an unspecified, platform-specific, self-synchronizing superset of UTF-8. + /// By being a self-synchronizing superset of UTF-8, this encoding is also a superset of 7-bit + /// ASCII. + /// + /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should + /// be treated as opaque and only comparable within the same rust version built for the same + /// target platform. For example, sending the bytes over the network or storing it in a file + /// will likely result in incompatible data. See [`OsString`] for more encoding details + /// and [`std::ffi`] for platform-specific, specified conversions. + /// + /// [`std::ffi`]: crate::ffi + #[inline] + #[unstable(feature = "os_str_bytes", issue = "111544")] + pub fn into_os_str_bytes(self) -> Vec<u8> { + self.inner.into_os_str_bytes() + } + /// Converts the `OsString` into a [`String`] if it contains valid Unicode data. /// /// On failure, ownership of the original `OsString` is returned. |
