From c77d58fad8b484abdc0140d5adb27c738d46f261 Mon Sep 17 00:00:00 2001 From: Ben Striegel Date: Fri, 31 May 2013 18:11:38 -0400 Subject: [PATCH] Add as_c_str method on strings --- src/libstd/prelude.rs | 2 +- src/libstd/str.rs | 61 +++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 4dcef60781f5d..5a5efa0781ae9 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -45,7 +45,7 @@ pub use path::PosixPath; pub use path::WindowsPath; pub use ptr::Ptr; pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr}; -pub use str::{StrSlice, OwnedStr}; +pub use str::{StrSlice, OwnedStr, StrUtil}; pub use from_str::{FromStr}; pub use to_bytes::IterBytes; pub use to_str::{ToStr, ToStrConsume}; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 4d41f10fdfcad..c9452ed543364 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -2165,33 +2165,50 @@ pub fn as_bytes_slice<'a>(s: &'a str) -> &'a [u8] { } /** - * Work with the byte buffer of a string as a null-terminated C string. - * - * Allows for unsafe manipulation of strings, which is useful for foreign - * interop. This is similar to `str::as_buf`, but guarantees null-termination. - * If the given slice is not already null-terminated, this function will - * allocate a temporary, copy the slice, null terminate it, and pass - * that instead. - * - * # Example - * - * ~~~ {.rust} - * let s = str::as_c_str("PATH", { |path| libc::getenv(path) }); - * ~~~ + * A dummy trait to hold all the utility methods that we implement on strings. */ -#[inline] -pub fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { - do as_buf(s) |buf, len| { - // NB: len includes the trailing null. - assert!(len > 0); - if unsafe { *(ptr::offset(buf,len-1)) != 0 } { - as_c_str(to_owned(s), f) - } else { - f(buf as *libc::c_char) +pub trait StrUtil { + /** + * Work with the byte buffer of a string as a null-terminated C string. + * + * Allows for unsafe manipulation of strings, which is useful for foreign + * interop. This is similar to `str::as_buf`, but guarantees null-termination. + * If the given slice is not already null-terminated, this function will + * allocate a temporary, copy the slice, null terminate it, and pass + * that instead. + * + * # Example + * + * ~~~ {.rust} + * let s = "PATH".as_c_str(|path| libc::getenv(path)); + * ~~~ + */ + fn as_c_str(self, f: &fn(*libc::c_char) -> T) -> T; +} + +impl<'self> StrUtil for &'self str { + #[inline] + fn as_c_str(self, f: &fn(*libc::c_char) -> T) -> T { + do as_buf(self) |buf, len| { + // NB: len includes the trailing null. + assert!(len > 0); + if unsafe { *(ptr::offset(buf,len-1)) != 0 } { + to_owned(self).as_c_str(f) + } else { + f(buf as *libc::c_char) + } } } } +/** + * Deprecated. Use the `as_c_str` method on strings instead. + */ +#[inline(always)] +pub fn as_c_str(s: &str, f: &fn(*libc::c_char) -> T) -> T { + s.as_c_str(f) +} + /** * Work with the byte buffer and length of a slice. *