use libc::c_char;
use std::ffi::{CStr, CString};
#[cfg(not(target_os = "linux"))]
pub trait AsCChars {
fn as_c_chars(&self) -> Option<*const c_char>;
}
#[cfg(not(target_os = "linux"))]
impl AsCChars for Option<&CString> {
fn as_c_chars(&self) -> Option<*const c_char> {
self.map(|s| s.as_ptr() as *const c_char)
}
}
pub unsafe fn raw_to_str<'a>(s: *const c_char) -> &'a str {
assert_not_null!(s);
unsafe {
CStr::from_ptr(s)
.to_str()
.expect("could not convert raw to str")
}
}
pub unsafe fn copy_raw(s: *const c_char) -> String {
assert_not_null!(s);
String::from(unsafe { raw_to_str(s) })
}
pub fn to_str(s: &CString) -> &str {
s.to_str().expect("could not convert CString to str")
}
#[cfg(test)]
mod tests {
use super::*;
use libc::c_char;
use std::ptr;
#[test]
fn raw_to_str_success() {
let c_string = c_string!("foo");
unsafe { assert_eq!(raw_to_str(c_string.as_ptr() as *const c_char), "foo") };
}
#[test]
#[should_panic]
fn raw_to_str_expects_non_null() {
unsafe { raw_to_str(ptr::null() as *const c_char) };
}
#[test]
fn copy_raw_success() {
let c_string = c_string!("foo");
let c_str = c_string.as_ptr() as *const c_char;
unsafe { assert_eq!(copy_raw(c_str), "foo".to_string()) };
}
#[test]
#[should_panic]
fn copy_raw_expects_non_null() {
unsafe { copy_raw(ptr::null() as *const c_char) };
}
}