use crate::raw;
use std::ffi::c_void;
use crate::Runtime;
struct WithGuileData<F, R> {
callback: Option<F>,
result: Option<R>,
}
pub fn with_guile<F, R>(f: F) -> R
where
F: FnOnce(&Runtime) -> R,
{
let mut data = WithGuileData {
callback: Some(f),
result: None,
};
unsafe {
raw::scm_with_guile(
Some(with_guile_callback::<F, R>),
&mut data as *mut _ as *mut c_void,
);
}
data.result.expect("callback should have set result")
}
unsafe extern "C" fn with_guile_callback<F, R>(data: *mut c_void) -> *mut c_void
where
F: FnOnce(&Runtime) -> R,
{
let data = unsafe{ &mut *(data as *mut WithGuileData<F, R>) };
let callback = data.callback.take().expect("callback already called");
let runtime = Runtime {};
let result = callback(&runtime);
data.result = Some(result);
std::ptr::null_mut()
}
struct WithoutGuileData<F, R> {
callback: Option<F>,
result: Option<R>,
}
pub fn without_guile<F, R>(f: F) -> R
where
F: FnOnce() -> R, {
let mut data = WithoutGuileData {
callback: Some(f),
result: None,
};
unsafe {
raw::scm_without_guile(
Some(without_guile_callback::<F, R>),
&mut data as *mut _ as *mut c_void,
);
}
data.result.expect("callback should have set result")
}
unsafe extern "C" fn without_guile_callback<F, R>(data: *mut c_void) -> *mut c_void
where
F: FnOnce() -> R,
{
let data = unsafe { &mut *(data as *mut WithoutGuileData<F, R>) };
let callback = data.callback.take().expect("callback already called");
let result = callback();
data.result = Some(result);
std::ptr::null_mut()
}