diff options
| author | bors <bors@rust-lang.org> | 2015-07-10 14:52:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-07-10 14:52:48 +0000 |
| commit | fddfd089b75379f1d25f81541572d69a93f95c4f (patch) | |
| tree | 0c5bb22a9600f6b62e96e7e1ef60f1f1a846237b | |
| parent | cdcce3ba4491436e6603833cee19533003993117 (diff) | |
| parent | 69579e4d37849fe64cbdfc7e40dc614af802704d (diff) | |
| download | rust-fddfd089b75379f1d25f81541572d69a93f95c4f.tar.gz rust-fddfd089b75379f1d25f81541572d69a93f95c4f.zip | |
Auto merge of #26928 - reem:cstr-is-a-cow, r=Gankro
This allows CString and CStr to be used with the Cow type, which is extremely useful when interfacing with C libraries that make extensive use of C-style strings.
| -rw-r--r-- | src/libstd/ffi/c_str.rs | 40 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 2 |
2 files changed, 40 insertions, 2 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index ffc204ada60..f13c10156f5 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use borrow::{Cow, ToOwned}; +use borrow::{Cow, ToOwned, Borrow}; use boxed::Box; use clone::Clone; use convert::{Into, From}; @@ -272,6 +272,11 @@ impl fmt::Debug for CString { } } +#[stable(feature = "cstr_borrow", since = "1.3.0")] +impl Borrow<CStr> for CString { + fn borrow(&self) -> &CStr { self } +} + impl NulError { /// Returns the position of the nul byte in the slice that was provided to /// `CString::new`. @@ -444,6 +449,15 @@ impl Ord for CStr { } } +#[stable(feature = "cstr_borrow", since = "1.3.0")] +impl ToOwned for CStr { + type Owned = CString; + + fn to_owned(&self) -> CString { + unsafe { CString::from_vec_unchecked(self.to_bytes().to_vec()) } + } +} + #[cfg(test)] mod tests { use prelude::v1::*; @@ -515,4 +529,28 @@ mod tests { assert_eq!(CStr::from_ptr(ptr).to_string_lossy(), Owned::<str>(format!("123\u{FFFD}"))); } } + + #[test] + fn to_owned() { + let data = b"123\0"; + let ptr = data.as_ptr() as *const libc::c_char; + + let owned = unsafe { CStr::from_ptr(ptr).to_owned() }; + assert_eq!(owned.as_bytes_with_nul(), data); + } + + #[test] + fn equal_hash() { + use hash; + + let data = b"123\xE2\xFA\xA6\0"; + let ptr = data.as_ptr() as *const libc::c_char; + let cstr: &'static CStr = unsafe { CStr::from_ptr(ptr) }; + + let cstr_hash = hash::hash::<_, hash::SipHasher>(&cstr); + let cstring_hash = + hash::hash::<_, hash::SipHasher>(&CString::new(&data[..data.len() - 1]).unwrap()); + + assert_eq!(cstr_hash, cstring_hash); + } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index caf3f497e10..1e82a03f286 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -150,7 +150,7 @@ #![feature(wrapping)] #![feature(zero_one)] #![cfg_attr(windows, feature(str_utf16))] -#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))] +#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras, hash_default))] #![cfg_attr(test, feature(test, rustc_private, float_consts))] #![cfg_attr(target_env = "msvc", feature(link_args))] |
