-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Implement TryFrom<OsString> for String
#151822
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ use crate::hash::{Hash, Hasher}; | |
| use crate::ops::{self, Range}; | ||
| use crate::rc::Rc; | ||
| use crate::str::FromStr; | ||
| use crate::string::FromUtf8Error; | ||
| use crate::sync::Arc; | ||
| use crate::sys::os_str::{Buf, Slice}; | ||
| use crate::sys::{AsInner, FromInner, IntoInner}; | ||
|
|
@@ -616,6 +617,43 @@ impl From<String> for OsString { | |
| } | ||
| } | ||
|
|
||
| #[stable(feature = "tryfrom_os_string_for_string", since = "CURRENT_RUSTC_VERSION")] | ||
| impl TryFrom<OsString> for String { | ||
| type Error = FromUtf8Error<OsString>; | ||
|
|
||
| /// Attempts to convert an [`OsString`] into a [`String`]. | ||
| /// | ||
| /// This conversion does not allocate or copy memory. | ||
| fn try_from(s: OsString) -> Result<Self, Self::Error> { | ||
| unsafe { | ||
| match s.as_os_str().inner.to_str() { | ||
| Ok(_) => Ok(String::from_utf8_unchecked(s.into_encoded_bytes())), | ||
| Err(error) => Err(FromUtf8Error { input: s, error }), | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl FromUtf8Error<OsString> { | ||
| /// Returns an [`OsStr`] slice that was attempted to convert to a `String`. | ||
| #[stable(feature = "tryfrom_os_string_for_string", since = "CURRENT_RUSTC_VERSION")] | ||
| #[rustc_allow_incoherent_impl] | ||
| pub fn as_os_str(&self) -> &OsStr { | ||
| &self.input[..] | ||
| } | ||
|
|
||
| /// Returns the [`OsString`] that was attempted to convert to a `String`. | ||
| /// | ||
| /// This method is carefully constructed to avoid allocation. It will | ||
| /// consume the error, moving out the string, so that a copy of the string | ||
| /// does not need to be made. | ||
| #[stable(feature = "tryfrom_os_string_for_string", since = "CURRENT_RUSTC_VERSION")] | ||
| #[rustc_allow_incoherent_impl] | ||
| pub fn into_os_string(self) -> OsString { | ||
| self.input | ||
| } | ||
|
Comment on lines
+638
to
+654
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These can be added unstably (unlike traits). I think it will probably be fine to put up a stabilization PR shortly after this merges.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. technically trait impls can be unstable too (afaik they actually work now), but idk if it's standard practice to use that yet.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎉 that's news to me! I think we may as well try it
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see https://rustc-dev-guide.rust-lang.org/stability.html#unstable_feature_bound for docs. #[unstable(feature = "tryfrom_os_string_for_string", issue = "NNN")]
#[unstable_feature_bound(tryfrom_os_string_for_string)]
impl TryFrom<OsString> for String {
...
}
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also, you'll want to add |
||
| } | ||
|
|
||
| #[stable(feature = "rust1", since = "1.0.0")] | ||
| impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString { | ||
| /// Copies any value implementing <code>[AsRef]<[OsStr]></code> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does technically copy memory, just not the contents of the
OsString.The docs should probably be based on the docs of
OsString::into_string:rust/library/std/src/ffi/os_str.rs
Lines 227 to 239 in 36e2b8a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I copied it from some other method that says the same thing in such scenario. I will look into it.