Skip to content

Commit e3a1a11

Browse files
committed
Implement TryFrom<&OsStr> for &str
1 parent 0075bb4 commit e3a1a11

File tree

5 files changed

+27
-14
lines changed

5 files changed

+27
-14
lines changed

library/std/src/ffi/os_str.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ impl OsStr {
692692
without modifying the original"]
693693
#[inline]
694694
pub fn to_str(&self) -> Option<&str> {
695-
self.inner.to_str()
695+
self.inner.to_str().ok()
696696
}
697697

698698
/// Converts an `OsStr` to a <code>[Cow]<[str]></code>.
@@ -1101,6 +1101,24 @@ impl<'a> From<Cow<'a, OsStr>> for OsString {
11011101
}
11021102
}
11031103

1104+
#[stable(feature = "str_tryfrom_osstr_impl", since = "CURRENT_RUSTC_VERSION")]
1105+
impl<'a> TryFrom<&'a OsStr> for &'a str {
1106+
type Error = crate::str::Utf8Error;
1107+
1108+
/// Tries to convert an `&OsStr` to a `&str`.
1109+
///
1110+
/// ```
1111+
/// use std::ffi::OsStr;
1112+
///
1113+
/// let os_str = OsStr::new("foo");
1114+
/// let as_str = <&str>::try_from(os_str).unwrap();
1115+
/// assert_eq!(as_str, "foo");
1116+
/// ```
1117+
fn try_from(value: &'a OsStr) -> Result<Self, Self::Error> {
1118+
value.inner.to_str()
1119+
}
1120+
}
1121+
11041122
#[stable(feature = "box_default_extra", since = "1.17.0")]
11051123
impl Default for Box<OsStr> {
11061124
#[inline]

library/std/src/sys/unix/os_str.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ impl Slice {
195195
Slice::from_u8_slice(s.as_bytes())
196196
}
197197

198-
pub fn to_str(&self) -> Option<&str> {
199-
str::from_utf8(&self.inner).ok()
198+
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
199+
str::from_utf8(&self.inner)
200200
}
201201

202202
pub fn to_string_lossy(&self) -> Cow<'_, str> {

library/std/src/sys/windows/os_str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl Slice {
155155
unsafe { mem::transmute(Wtf8::from_str(s)) }
156156
}
157157

158-
pub fn to_str(&self) -> Option<&str> {
158+
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
159159
self.inner.as_str()
160160
}
161161

library/std/src/sys_common/wtf8.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -566,13 +566,8 @@ impl Wtf8 {
566566
///
567567
/// This does not copy the data.
568568
#[inline]
569-
pub fn as_str(&self) -> Option<&str> {
570-
// Well-formed WTF-8 is also well-formed UTF-8
571-
// if and only if it contains no surrogate.
572-
match self.next_surrogate(0) {
573-
None => Some(unsafe { str::from_utf8_unchecked(&self.bytes) }),
574-
Some(_) => None,
575-
}
569+
pub fn as_str(&self) -> Result<&str, str::Utf8Error> {
570+
str::from_utf8(&self.bytes)
576571
}
577572

578573
/// Lossily converts the string to UTF-8.

library/std/src/sys_common/wtf8/tests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,11 @@ fn wtf8_code_points() {
354354

355355
#[test]
356356
fn wtf8_as_str() {
357-
assert_eq!(Wtf8::from_str("").as_str(), Some(""));
358-
assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩"));
357+
assert_eq!(Wtf8::from_str("").as_str(), Ok(""));
358+
assert_eq!(Wtf8::from_str("aé 💩").as_str(), Ok("aé 💩"));
359359
let mut string = Wtf8Buf::new();
360360
string.push(CodePoint::from_u32(0xD800).unwrap());
361-
assert_eq!(string.as_str(), None);
361+
assert!(string.as_str().is_err());
362362
}
363363

364364
#[test]

0 commit comments

Comments
 (0)