diff options
| author | bors <bors@rust-lang.org> | 2015-10-19 17:05:40 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-10-19 17:05:40 +0000 |
| commit | c74454a36040ed1b671ce31b5fcdc8755d11ce95 (patch) | |
| tree | ce95dd24d93d5d6c5cdbc921eb0ffc6b7b3fc21d /src | |
| parent | 7aec91734e0c12b8e36158566ad512a663111c9f (diff) | |
| parent | cb48d4458377904103ca0254bf9270ee1a2426be (diff) | |
| download | rust-c74454a36040ed1b671ce31b5fcdc8755d11ce95.tar.gz rust-c74454a36040ed1b671ce31b5fcdc8755d11ce95.zip | |
Auto merge of #28977 - arcnmx:cstring-into, r=alexcrichton
`OsString` has these sorts of conversions, while `CString` has been missing them. I'm iffy on `into_string` simply because the return type would be better off as `FromUtf8Error<CString>`, which of course isn't generic :cry: Also should a different/new feature gate be used?
Diffstat (limited to 'src')
| -rw-r--r-- | src/libstd/ffi/c_str.rs | 72 | ||||
| -rw-r--r-- | src/libstd/ffi/mod.rs | 2 |
2 files changed, 72 insertions, 2 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 6b7ecaa77d1..89427f7851b 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -23,7 +23,7 @@ use ops::Deref; use option::Option::{self, Some, None}; use result::Result::{self, Ok, Err}; use slice; -use str; +use str::{self, Utf8Error}; use string::String; use vec::Vec; @@ -151,6 +151,15 @@ pub struct CStr { #[stable(feature = "rust1", since = "1.0.0")] pub struct NulError(usize, Vec<u8>); +/// An error returned from `CString::into_string` to indicate that a UTF-8 error +/// was encountered during the conversion. +#[derive(Clone, PartialEq, Debug)] +#[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] +pub struct IntoStringError { + inner: CString, + error: Utf8Error, +} + impl CString { /// Creates a new C-compatible string from a container of bytes. /// @@ -255,6 +264,38 @@ impl CString { Box::into_raw(self.inner) as *mut libc::c_char } + /// Converts the `CString` into a `String` if it contains valid Unicode data. + /// + /// On failure, ownership of the original `CString` is returned. + #[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] + pub fn into_string(self) -> Result<String, IntoStringError> { + String::from_utf8(self.into_bytes()) + .map_err(|e| IntoStringError { + error: e.utf8_error(), + inner: unsafe { CString::from_vec_unchecked(e.into_bytes()) }, + }) + } + + /// Returns the underlying byte buffer. + /// + /// The returned buffer does **not** contain the trailing nul separator and + /// it is guaranteed to not have any interior nul bytes. + #[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] + pub fn into_bytes(self) -> Vec<u8> { + // FIXME: Once this method becomes stable, add an `impl Into<Vec<u8>> for CString` + let mut vec = self.inner.into_vec(); + let _nul = vec.pop(); + debug_assert_eq!(_nul, Some(0u8)); + vec + } + + /// Equivalent to the `into_bytes` function except that the returned vector + /// includes the trailing nul byte. + #[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] + pub fn into_bytes_with_nul(self) -> Vec<u8> { + self.inner.into_vec() + } + /// Returns the contents of this `CString` as a slice of bytes. /// /// The returned slice does **not** contain the trailing nul separator and @@ -336,6 +377,35 @@ impl From<NulError> for io::Error { } } +impl IntoStringError { + /// Consumes this error, returning original `CString` which generated the + /// error. + #[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] + pub fn into_cstring(self) -> CString { + self.inner + } + + /// Access the underlying UTF-8 error that was the cause of this error. + #[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] + pub fn utf8_error(&self) -> Utf8Error { + self.error + } +} + +#[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] +impl Error for IntoStringError { + fn description(&self) -> &str { + Error::description(&self.error) + } +} + +#[unstable(feature = "cstring_into", reason = "recently added", issue = "29157")] +impl fmt::Display for IntoStringError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.error, f) + } +} + impl CStr { /// Casts a raw C string to a safe C string wrapper. /// diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs index dfe706e0773..bfd6ab52289 100644 --- a/src/libstd/ffi/mod.rs +++ b/src/libstd/ffi/mod.rs @@ -13,7 +13,7 @@ #![stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")] -pub use self::c_str::{CString, CStr, NulError}; +pub use self::c_str::{CString, CStr, NulError, IntoStringError}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::{OsString, OsStr}; |
