Skip to content

Commit aaa5889

Browse files
authored
Rollup merge of rust-lang#120051 - riverbl:os-str-display, r=m-ou-se
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 (see rust-lang/libs-team#326 (comment)). - ACP: rust-lang/libs-team#326 - Tracking issue: rust-lang#120048
2 parents 1e4f9e3 + a0fcc8e commit aaa5889

File tree

4 files changed

+73
-10
lines changed

4 files changed

+73
-10
lines changed

library/std/src/ffi/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ pub use core::ffi::FromBytesUntilNulError;
169169
pub use core::ffi::{CStr, FromBytesWithNulError};
170170

171171
#[stable(feature = "rust1", since = "1.0.0")]
172+
#[doc(inline)]
172173
pub use self::os_str::{OsStr, OsString};
173174

174175
#[stable(feature = "core_ffi_c", since = "1.64.0")]
@@ -188,4 +189,5 @@ pub use core::ffi::c_void;
188189
)]
189190
pub use core::ffi::{VaList, VaListImpl};
190191

191-
mod os_str;
192+
#[unstable(feature = "os_str_display", issue = "120048")]
193+
pub mod os_str;

library/std/src/ffi/os_str.rs

+64-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! The [`OsStr`] and [`OsString`] types and associated utilities.
2+
13
#[cfg(test)]
24
mod tests;
35

@@ -1147,6 +1149,32 @@ impl OsStr {
11471149
pub fn eq_ignore_ascii_case<S: AsRef<OsStr>>(&self, other: S) -> bool {
11481150
self.inner.eq_ignore_ascii_case(&other.as_ref().inner)
11491151
}
1152+
1153+
/// Returns an object that implements [`Display`] for safely printing an
1154+
/// [`OsStr`] that may contain non-Unicode data. This may perform lossy
1155+
/// conversion, depending on the platform. If you would like an
1156+
/// implementation which escapes the [`OsStr`] please use [`Debug`]
1157+
/// instead.
1158+
///
1159+
/// [`Display`]: fmt::Display
1160+
/// [`Debug`]: fmt::Debug
1161+
///
1162+
/// # Examples
1163+
///
1164+
/// ```
1165+
/// #![feature(os_str_display)]
1166+
/// use std::ffi::OsStr;
1167+
///
1168+
/// let s = OsStr::new("Hello, world!");
1169+
/// println!("{}", s.display());
1170+
/// ```
1171+
#[unstable(feature = "os_str_display", issue = "120048")]
1172+
#[must_use = "this does not display the `OsStr`; \
1173+
it returns an object that can be displayed"]
1174+
#[inline]
1175+
pub fn display(&self) -> Display<'_> {
1176+
Display { os_str: self }
1177+
}
11501178
}
11511179

11521180
#[stable(feature = "box_from_os_str", since = "1.17.0")]
@@ -1441,9 +1469,42 @@ impl fmt::Debug for OsStr {
14411469
}
14421470
}
14431471

1444-
impl OsStr {
1445-
pub(crate) fn display(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1446-
fmt::Display::fmt(&self.inner, formatter)
1472+
/// Helper struct for safely printing an [`OsStr`] with [`format!`] and `{}`.
1473+
///
1474+
/// An [`OsStr`] might contain non-Unicode data. This `struct` implements the
1475+
/// [`Display`] trait in a way that mitigates that. It is created by the
1476+
/// [`display`](OsStr::display) method on [`OsStr`]. This may perform lossy
1477+
/// conversion, depending on the platform. If you would like an implementation
1478+
/// which escapes the [`OsStr`] please use [`Debug`] instead.
1479+
///
1480+
/// # Examples
1481+
///
1482+
/// ```
1483+
/// #![feature(os_str_display)]
1484+
/// use std::ffi::OsStr;
1485+
///
1486+
/// let s = OsStr::new("Hello, world!");
1487+
/// println!("{}", s.display());
1488+
/// ```
1489+
///
1490+
/// [`Display`]: fmt::Display
1491+
/// [`format!`]: crate::format
1492+
#[unstable(feature = "os_str_display", issue = "120048")]
1493+
pub struct Display<'a> {
1494+
os_str: &'a OsStr,
1495+
}
1496+
1497+
#[unstable(feature = "os_str_display", issue = "120048")]
1498+
impl fmt::Debug for Display<'_> {
1499+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1500+
fmt::Debug::fmt(&self.os_str, f)
1501+
}
1502+
}
1503+
1504+
#[unstable(feature = "os_str_display", issue = "120048")]
1505+
impl fmt::Display for Display<'_> {
1506+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1507+
fmt::Display::fmt(&self.os_str.inner, f)
14471508
}
14481509
}
14491510

library/std/src/path.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ use crate::rc::Rc;
8484
use crate::str::FromStr;
8585
use crate::sync::Arc;
8686

87-
use crate::ffi::{OsStr, OsString};
87+
use crate::ffi::{os_str, OsStr, OsString};
8888
use crate::sys;
8989
use crate::sys::path::{is_sep_byte, is_verbatim_sep, parse_prefix, MAIN_SEP_STR};
9090

@@ -2726,7 +2726,7 @@ impl Path {
27262726
it returns an object that can be displayed"]
27272727
#[inline]
27282728
pub fn display(&self) -> Display<'_> {
2729-
Display { path: self }
2729+
Display { inner: self.inner.display() }
27302730
}
27312731

27322732
/// Queries the file system to get information about a file, directory, etc.
@@ -3033,20 +3033,20 @@ impl fmt::Debug for Path {
30333033
/// [`format!`]: crate::format
30343034
#[stable(feature = "rust1", since = "1.0.0")]
30353035
pub struct Display<'a> {
3036-
path: &'a Path,
3036+
inner: os_str::Display<'a>,
30373037
}
30383038

30393039
#[stable(feature = "rust1", since = "1.0.0")]
30403040
impl fmt::Debug for Display<'_> {
30413041
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3042-
fmt::Debug::fmt(&self.path, f)
3042+
fmt::Debug::fmt(&self.inner, f)
30433043
}
30443044
}
30453045

30463046
#[stable(feature = "rust1", since = "1.0.0")]
30473047
impl fmt::Display for Display<'_> {
30483048
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3049-
self.path.inner.display(f)
3049+
fmt::Display::fmt(&self.inner, f)
30503050
}
30513051
}
30523052

tests/rustdoc-js-std/osstring-to-string.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
const EXPECTED = {
55
'query': 'OsString -> String',
66
'others': [
7-
{ 'path': 'std::ffi::OsString', 'name': 'into_string' },
7+
{ 'path': 'std::ffi::os_str::OsString', 'name': 'into_string' },
88
]
99
};

0 commit comments

Comments
 (0)