Skip to content

Commit

Permalink
Implement TryFrom<&OsStr> for &str
Browse files Browse the repository at this point in the history
  • Loading branch information
aticu committed Jun 12, 2023
1 parent 0075bb4 commit e3a1a11
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 14 deletions.
20 changes: 19 additions & 1 deletion library/std/src/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ impl OsStr {
without modifying the original"]
#[inline]
pub fn to_str(&self) -> Option<&str> {
self.inner.to_str()
self.inner.to_str().ok()
}

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

#[stable(feature = "str_tryfrom_osstr_impl", since = "CURRENT_RUSTC_VERSION")]
impl<'a> TryFrom<&'a OsStr> for &'a str {
type Error = crate::str::Utf8Error;

/// Tries to convert an `&OsStr` to a `&str`.
///
/// ```
/// use std::ffi::OsStr;
///
/// let os_str = OsStr::new("foo");
/// let as_str = <&str>::try_from(os_str).unwrap();
/// assert_eq!(as_str, "foo");
/// ```
fn try_from(value: &'a OsStr) -> Result<Self, Self::Error> {
value.inner.to_str()
}
}

#[stable(feature = "box_default_extra", since = "1.17.0")]
impl Default for Box<OsStr> {
#[inline]
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/sys/unix/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ impl Slice {
Slice::from_u8_slice(s.as_bytes())
}

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

pub fn to_string_lossy(&self) -> Cow<'_, str> {
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/windows/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl Slice {
unsafe { mem::transmute(Wtf8::from_str(s)) }
}

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

Expand Down
9 changes: 2 additions & 7 deletions library/std/src/sys_common/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,13 +566,8 @@ impl Wtf8 {
///
/// This does not copy the data.
#[inline]
pub fn as_str(&self) -> Option<&str> {
// Well-formed WTF-8 is also well-formed UTF-8
// if and only if it contains no surrogate.
match self.next_surrogate(0) {
None => Some(unsafe { str::from_utf8_unchecked(&self.bytes) }),
Some(_) => None,
}
pub fn as_str(&self) -> Result<&str, str::Utf8Error> {
str::from_utf8(&self.bytes)
}

/// Lossily converts the string to UTF-8.
Expand Down
6 changes: 3 additions & 3 deletions library/std/src/sys_common/wtf8/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,11 +354,11 @@ fn wtf8_code_points() {

#[test]
fn wtf8_as_str() {
assert_eq!(Wtf8::from_str("").as_str(), Some(""));
assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩"));
assert_eq!(Wtf8::from_str("").as_str(), Ok(""));
assert_eq!(Wtf8::from_str("aé 💩").as_str(), Ok("aé 💩"));
let mut string = Wtf8Buf::new();
string.push(CodePoint::from_u32(0xD800).unwrap());
assert_eq!(string.as_str(), None);
assert!(string.as_str().is_err());
}

#[test]
Expand Down

0 comments on commit e3a1a11

Please sign in to comment.