c_str: add `.as_ptr` & `.as_mut_ptr` to replace `.with_[mut_]ref`.
These forms return the pointer directly, rather than the added indirection, indentation, and inefficiencies of the closures in `.with_ref` and `.with_mut_ref`. The two closure functions are deprecated. Replace foo(c_str.with_ref(|p| p)) c_str.with_ref(|p| { foo(p); bar(p); }) with foo(c_str.as_ptr()) let p = c_str.as_ptr(); foo(p); bar(p); This change does mean that one has to be careful to avoid writing `let p = x.to_c_str().as_ptr();` since the `CString` will be freed at the end of the statement. Previously, `with_ref` was used (and `as_ptr` avoided) for this reason, but Rust has strongly moved away from closures to more RAII-style code, and most uses of `.with_ref` where in the form `.with_ref(|p| p)` anyway, that is, they were exactly `.as_ptr`. [breaking-change]
This commit is contained in:
parent
6a3695d54f
commit
2c9aada10c
|
@ -133,11 +133,79 @@ impl CString {
|
|||
c_str.buf
|
||||
}
|
||||
|
||||
/// Return a pointer to the NUL-terminated string data.
|
||||
///
|
||||
/// `.as_ptr` returns an internal pointer into the `CString`, and
|
||||
/// may be invalidated when the `CString` falls out of scope (the
|
||||
/// destructor will run, freeing the allocation if there is
|
||||
/// one).
|
||||
///
|
||||
/// ```rust
|
||||
/// let foo = "some string";
|
||||
///
|
||||
/// // right
|
||||
/// let x = foo.to_c_str();
|
||||
/// let p = x.as_ptr();
|
||||
///
|
||||
/// // wrong (the CString will be freed, invalidating `p`)
|
||||
/// let p = foo.to_c_str().as_ptr();
|
||||
/// ```
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// extern crate libc;
|
||||
///
|
||||
/// fn main() {
|
||||
/// let c_str = "foo bar".to_c_str();
|
||||
/// unsafe {
|
||||
/// libc::puts(c_str.as_ptr());
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn as_ptr(&self) -> *const libc::c_char {
|
||||
if self.buf.is_null() { fail!("CString is null!"); }
|
||||
|
||||
self.buf
|
||||
}
|
||||
|
||||
/// Return a mutable pointer to the NUL-terminated string data.
|
||||
///
|
||||
/// `.as_mut_ptr` returns an internal pointer into the `CString`, and
|
||||
/// may be invalidated when the `CString` falls out of scope (the
|
||||
/// destructor will run, freeing the allocation if there is
|
||||
/// one).
|
||||
///
|
||||
/// ```rust
|
||||
/// let foo = "some string";
|
||||
///
|
||||
/// // right
|
||||
/// let mut x = foo.to_c_str();
|
||||
/// let p = x.as_mut_ptr();
|
||||
///
|
||||
/// // wrong (the CString will be freed, invalidating `p`)
|
||||
/// let p = foo.to_c_str().as_mut_ptr();
|
||||
/// ```
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
pub fn as_mut_ptr(&mut self) -> *mut libc::c_char {
|
||||
if self.buf.is_null() { fail!("CString is null!") }
|
||||
|
||||
self.buf as *mut _
|
||||
}
|
||||
|
||||
/// Calls a closure with a reference to the underlying `*libc::c_char`.
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
#[deprecated="use `.as_ptr()`"]
|
||||
pub fn with_ref<T>(&self, f: |*const libc::c_char| -> T) -> T {
|
||||
if self.buf.is_null() { fail!("CString is null!"); }
|
||||
f(self.buf)
|
||||
|
@ -148,6 +216,7 @@ impl CString {
|
|||
/// # Failure
|
||||
///
|
||||
/// Fails if the CString is null.
|
||||
#[deprecated="use `.as_mut_ptr()`"]
|
||||
pub fn with_mut_ref<T>(&mut self, f: |*mut libc::c_char| -> T) -> T {
|
||||
if self.buf.is_null() { fail!("CString is null!"); }
|
||||
f(self.buf as *mut libc::c_char)
|
||||
|
|
Loading…
Reference in New Issue