about summary refs log tree commit diff
path: root/library/std/src/ffi/os_str.rs
diff options
context:
space:
mode:
authorriverbl <94326797+riverbl@users.noreply.github.com>2024-01-07 13:58:39 +0000
committerriverbl <94326797+riverbl@users.noreply.github.com>2024-01-18 20:38:31 +0000
commita0fcc8ebc0793afd66be06db3c338b0b4d43fe3c (patch)
treecc04ad8b33cb15e27dd409f9018af803f403e5b3 /library/std/src/ffi/os_str.rs
parent8424f8e8cdf07010967a57584fd647b30e930d4d (diff)
downloadrust-a0fcc8ebc0793afd66be06db3c338b0b4d43fe3c.tar.gz
rust-a0fcc8ebc0793afd66be06db3c338b0b4d43fe3c.zip
Add `display` method to `OsStr`
Add `display` method to `OsStr` for lossy display of an `OsStr` which may contain invalid unicode.

Invalid Unicode sequences are replaced with `U+FFFD REPLACEMENT CHARACTER`.

This change also makes the `std::ffi::os_str` module public.
Diffstat (limited to 'library/std/src/ffi/os_str.rs')
-rw-r--r--library/std/src/ffi/os_str.rs67
1 files changed, 64 insertions, 3 deletions
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 81973182148..cd954f9e802 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -1,3 +1,5 @@
+//! The [`OsStr`] and [`OsString`] types and associated utilities.
+
 #[cfg(test)]
 mod tests;
 
@@ -1173,6 +1175,32 @@ impl OsStr {
     pub fn eq_ignore_ascii_case<S: AsRef<OsStr>>(&self, other: S) -> bool {
         self.inner.eq_ignore_ascii_case(&other.as_ref().inner)
     }
+
+    /// Returns an object that implements [`Display`] for safely printing an
+    /// [`OsStr`] that may contain non-Unicode data. This may perform lossy
+    /// conversion, depending on the platform.  If you would like an
+    /// implementation which escapes the [`OsStr`] please use [`Debug`]
+    /// instead.
+    ///
+    /// [`Display`]: fmt::Display
+    /// [`Debug`]: fmt::Debug
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(os_str_display)]
+    /// use std::ffi::OsStr;
+    ///
+    /// let s = OsStr::new("Hello, world!");
+    /// println!("{}", s.display());
+    /// ```
+    #[unstable(feature = "os_str_display", issue = "120048")]
+    #[must_use = "this does not display the `OsStr`; \
+                  it returns an object that can be displayed"]
+    #[inline]
+    pub fn display(&self) -> Display<'_> {
+        Display { os_str: self }
+    }
 }
 
 #[stable(feature = "box_from_os_str", since = "1.17.0")]
@@ -1467,9 +1495,42 @@ impl fmt::Debug for OsStr {
     }
 }
 
-impl OsStr {
-    pub(crate) fn display(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        fmt::Display::fmt(&self.inner, formatter)
+/// Helper struct for safely printing an [`OsStr`] with [`format!`] and `{}`.
+///
+/// An [`OsStr`] might contain non-Unicode data. This `struct` implements the
+/// [`Display`] trait in a way that mitigates that. It is created by the
+/// [`display`](OsStr::display) method on [`OsStr`]. This may perform lossy
+/// conversion, depending on the platform. If you would like an implementation
+/// which escapes the [`OsStr`] please use [`Debug`] instead.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(os_str_display)]
+/// use std::ffi::OsStr;
+///
+/// let s = OsStr::new("Hello, world!");
+/// println!("{}", s.display());
+/// ```
+///
+/// [`Display`]: fmt::Display
+/// [`format!`]: crate::format
+#[unstable(feature = "os_str_display", issue = "120048")]
+pub struct Display<'a> {
+    os_str: &'a OsStr,
+}
+
+#[unstable(feature = "os_str_display", issue = "120048")]
+impl fmt::Debug for Display<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(&self.os_str, f)
+    }
+}
+
+#[unstable(feature = "os_str_display", issue = "120048")]
+impl fmt::Display for Display<'_> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.os_str.inner, f)
     }
 }