about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJacob Pratt <jacob@jhpratt.dev>2025-05-29 04:50:47 +0200
committerGitHub <noreply@github.com>2025-05-29 04:50:47 +0200
commitba042d7cb1d74d97ad56a28c5ab79ff8459366e4 (patch)
treee4b2de68a314d0da718a74e738ac168fee8872c8
parent8951c74e2a5bd81710e178cb708257c0c5cd60da (diff)
parent947be5f4316088f44cf2db69d137fd9afbfd7723 (diff)
downloadrust-ba042d7cb1d74d97ad56a28c5ab79ff8459366e4.tar.gz
rust-ba042d7cb1d74d97ad56a28c5ab79ff8459366e4.zip
Rollup merge of #139994 - tamird:cstr-display, r=Amanieu
add `CStr::display`

The implementation delegates to `<ByteStr as Display>::fmt`.

Link: https://github.com/rust-lang/libs-team/issues/550
Link: https://github.com/rust-lang/rust/issues/139984.

r? ```@BurntSushi```
cc ```@Darksonn``` ```@tgross35``` ```@ojeda``` ```@joshtriplett```
-rw-r--r--library/core/src/ffi/c_str.rs24
-rw-r--r--library/coretests/tests/ffi/cstr.rs6
-rw-r--r--library/coretests/tests/lib.rs1
3 files changed, 31 insertions, 0 deletions
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index 825402116e5..bb2bf128be1 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -632,6 +632,30 @@ impl CStr {
         // instead of doing it afterwards.
         str::from_utf8(self.to_bytes())
     }
+
+    /// Returns an object that implements [`Display`] for safely printing a [`CStr`] that may
+    /// contain non-Unicode data.
+    ///
+    /// Behaves as if `self` were first lossily converted to a `str`, with invalid UTF-8 presented
+    /// as the Unicode replacement character: �.
+    ///
+    /// [`Display`]: fmt::Display
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(cstr_display)]
+    ///
+    /// let cstr = c"Hello, world!";
+    /// println!("{}", cstr.display());
+    /// ```
+    #[unstable(feature = "cstr_display", issue = "139984")]
+    #[must_use = "this does not display the `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())
+    }
 }
 
 // `.to_bytes()` representations are compared instead of the inner `[c_char]`s,
diff --git a/library/coretests/tests/ffi/cstr.rs b/library/coretests/tests/ffi/cstr.rs
index 0d85b22c585..dc34240cd99 100644
--- a/library/coretests/tests/ffi/cstr.rs
+++ b/library/coretests/tests/ffi/cstr.rs
@@ -19,3 +19,9 @@ fn debug() {
     let s = c"abc\x01\x02\n\xE2\x80\xA6\xFF";
     assert_eq!(format!("{s:?}"), r#""abc\x01\x02\n\xe2\x80\xa6\xff""#);
 }
+
+#[test]
+fn display() {
+    let s = c"\xf0\x28\x8c\xbc";
+    assert_eq!(format!("{}", s.display()), "�(��");
+}
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index b1301200981..693b14ef762 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -23,6 +23,7 @@
 #![feature(core_io_borrowed_buf)]
 #![feature(core_private_bignum)]
 #![feature(core_private_diy_float)]
+#![feature(cstr_display)]
 #![feature(dec2flt)]
 #![feature(duration_constants)]
 #![feature(duration_constructors)]