rosascript 0.1.2

faster dx with obj c ffi bindings
Documentation
use std::ffi::CString;
use std::sync::Mutex;
use once_cell::sync::Lazy;

extern crate libc;

extern "C" {
    fn executeAppleScript(script: *const libc::c_char) -> *const libc::c_char;
    fn compileAppleScript(script_source: *const libc::c_char) -> *mut libc::c_void;
    fn executeCompiledAppleScript(
        compiled_script: *mut libc::c_void,
        parameters: *const libc::c_char,
    ) -> *const libc::c_char;
    fn sendAppleEvent(
        compiled_script: *mut libc::c_void,
        event_code: *const libc::c_char,
        parameters: *const libc::c_char,
    ) -> *const libc::c_char;

}

static APPLE_SCRIPT_EXECUTOR: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));

pub fn run_apple_script(script: &str) -> String {
    let _lock = APPLE_SCRIPT_EXECUTOR.lock().unwrap();

    let c_script = CString::new(script).expect("CString::new failed");
    unsafe {
        let result = executeAppleScript(c_script.as_ptr());
        std::ffi::CStr::from_ptr(result)
            .to_string_lossy()
            .into_owned()
    }
}
pub fn compile_script(script: &str) -> *mut libc::c_void {
    let c_script = CString::new(script).unwrap();
    unsafe { compileAppleScript(c_script.as_ptr()) }
}

pub fn execute_script(compiled_script: *mut libc::c_void, parameters: &str) -> Option<String> {
    let c_parameters = CString::new(parameters).unwrap();
    unsafe {
        let result = executeCompiledAppleScript(compiled_script, c_parameters.as_ptr());
        if result.is_null() {
            None
        } else {
            Some(
                std::ffi::CStr::from_ptr(result)
                    .to_string_lossy()
                    .into_owned(),
            )
        }
    }
}

pub fn send_apple_event(
    compiled_script: *mut libc::c_void,
    event_code: &str,
    parameters: &str,
) -> Option<String> {
    let c_parameters = CString::new(parameters).unwrap();
    let c_event_code = CString::new(event_code).unwrap();
    unsafe {
        let result = sendAppleEvent(
            compiled_script,
            c_event_code.as_ptr(),
            c_parameters.as_ptr(),
        );
        if result.is_null() {
            None
        } else {
            Some(
                std::ffi::CStr::from_ptr(result)
                    .to_string_lossy()
                    .into_owned(),
            )
        }
    }
}