use std::ffi::{c_char, CStr, CString};
use crate::Value;
#[unsafe(no_mangle)]
pub extern "C" fn value_from_cstring(c_string: *const c_char) -> *mut Value {
if c_string.is_null() {
return std::ptr::null_mut();
}
let c_str = unsafe { CStr::from_ptr(c_string) };
let c_str = match c_str.to_str() {
Ok(s) => s,
Err(_) => return std::ptr::null_mut(),
};
if let Ok(val) = Value::try_from(c_str) {
Box::into_raw(Box::new(val))
} else {
std::ptr::null_mut()
}
}
#[unsafe(no_mangle)]
pub extern "C" fn cstring_from_value(value: *mut Value) -> *const c_char {
if value.is_null() {
return std::ptr::null();
}
unsafe {
match (&*value).clone().try_into() {
Ok(string) => match CString::new::<String>(string) {
Ok(cstr) => cstr.into_raw() as *const c_char,
Err(_) => std::ptr::null(),
},
Err(_) => std::ptr::null(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn cstring_free(cstr: *mut c_char) {
if cstr.is_null() {
return;
}
unsafe {
drop(CString::from_raw(cstr))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn cstring_len_from_value(value: *mut Value) -> usize {
if value.is_null() {
return 0;
}
let string: Result<String, _> = unsafe { (&*value).clone().try_into() };
string.map(|s| s.len()).unwrap_or(0)
}