use std::{
ffi::{CStr, CString},
os::raw::c_char,
ptr,
};
use crate::api::propagate_panic;
type FreeDartNativeStringFunction = extern "C" fn(ptr::NonNull<c_char>);
static mut FREE_DART_NATIVE_STRING: Option<FreeDartNativeStringFunction> = None;
#[must_use]
pub unsafe fn c_str_into_string(string: ptr::NonNull<c_char>) -> String {
unsafe { CStr::from_ptr(string.as_ptr()) }
.to_str()
.unwrap()
.to_owned()
}
#[must_use]
pub fn string_into_c_str(string: String) -> ptr::NonNull<c_char> {
ptr::NonNull::new(CString::new(string).unwrap().into_raw()).unwrap()
}
#[must_use]
pub unsafe fn dart_string_into_rust(
dart_string: ptr::NonNull<c_char>,
) -> String {
let rust_string = unsafe { c_str_into_string(dart_string) };
unsafe {
free_dart_native_string(dart_string);
}
rust_string
}
#[no_mangle]
pub unsafe extern "C" fn String_free(s: ptr::NonNull<c_char>) {
propagate_panic(move || {
drop(unsafe { CString::from_raw(s.as_ptr()) });
});
}
#[no_mangle]
pub unsafe extern "C" fn register_free_dart_native_string(
f: FreeDartNativeStringFunction,
) {
unsafe {
FREE_DART_NATIVE_STRING = Some(f);
}
}
pub unsafe fn free_dart_native_string(s: ptr::NonNull<c_char>) {
(unsafe { FREE_DART_NATIVE_STRING.unwrap() })(s);
}