1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
use libc::c_char;
use std::ffi::{CStr, CString};
use std::mem;
use std::str;
pub unsafe trait Sub<T>: Sized {
fn is(c: &T) -> bool;
fn from_super(c: &T) -> Option<&Self> {
if Self::is(c) {
Some(unsafe { mem::transmute(c) })
} else {
None
}
}
fn to_super(&self) -> &T {
unsafe { mem::transmute(self) }
}
}
#[inline(always)]
pub fn with_cstr<C, R>(text: &str, cb: C) -> R where C:FnOnce(*const c_char) -> R {
let c_text = CString::new(text).unwrap();
cb(c_text.as_bytes().as_ptr() as *const c_char)
}
#[inline(always)]
pub unsafe fn to_str<'a>(text: *mut c_char) -> &'a str {
let c_str = CStr::from_ptr(text);
str::from_utf8_unchecked(c_str.to_bytes())
}
pub unsafe fn to_null_str<'a>(text: *mut c_char) -> Option<&'a str> {
if text.is_null() {
None
} else {
Some(to_str(text))
}
}
pub unsafe fn ptr_to_null<P, T>(ptr: *mut P) -> Option<T> where T:From<*mut P> {
if ptr.is_null() {
None
} else {
Some(ptr.into())
}
}