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.
This commit is contained in:
commit
fddfd089b7
2 changed files with 40 additions and 2 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue