use std;
use std::os::raw::c_void;
use std::ptr::null_mut;
pub enum ListResult<T> {
Item(T),
End,
Error,
}
#[inline]
pub(crate) fn unwrap_optional_callback<T>(cb: Option<(T, *mut c_void)>) -> (Option<T>, *mut c_void) {
match cb {
Some((f, d)) => (Some(f), d),
None => (None, null_mut::<c_void>()),
}
}
pub(crate) struct MultiUseCallback<ClosureProto: ?Sized, ProxyProto> {
saved: Option<*mut Box<ClosureProto>>,
proxy: std::marker::PhantomData<*const ProxyProto>,
}
impl<ClosureProto: ?Sized, ProxyProto> Default for MultiUseCallback<ClosureProto, ProxyProto> {
fn default() -> Self {
MultiUseCallback::<ClosureProto, ProxyProto> { saved: None, proxy: std::marker::PhantomData }
}
}
impl<ClosureProto: ?Sized, ProxyProto> MultiUseCallback<ClosureProto, ProxyProto> {
pub fn new(cb: Option<Box<ClosureProto>>) -> Self {
match cb {
Some(f) => MultiUseCallback::<ClosureProto, ProxyProto> {
saved: Some(Box::into_raw(Box::new(f))),
proxy: std::marker::PhantomData,
},
None => Default::default(),
}
}
pub fn get_capi_params(&self, proxy: ProxyProto) -> (Option<ProxyProto>, *mut c_void) {
match self.saved {
Some(ref f) => (Some(proxy), *f as *mut c_void),
None => (None, std::ptr::null_mut::<c_void>()),
}
}
pub fn get_callback<'a>(ptr: *mut c_void) -> &'a mut Box<ClosureProto> {
assert!(!ptr.is_null());
unsafe { &mut *(ptr as *mut Box<ClosureProto>) }
}
}
impl<ClosureProto: ?Sized, ProxyProto> Drop for MultiUseCallback<ClosureProto, ProxyProto> {
fn drop(&mut self) {
if self.saved.is_some() {
let _to_drop = unsafe { Box::from_raw(self.saved.unwrap()) };
}
}
}
pub(crate) fn box_closure_get_capi_ptr<ClosureProto: ?Sized>(callback: Box<ClosureProto>
) -> *mut c_void
{
Box::into_raw(Box::new(callback)) as *mut c_void
}
pub(crate) fn get_su_capi_params<ClosureProto: ?Sized, ProxyProto>(
callback: Option<Box<ClosureProto>>, proxy: ProxyProto) -> (Option<ProxyProto>, *mut c_void)
{
match callback {
Some(f) => (Some(proxy), box_closure_get_capi_ptr::<ClosureProto>(f)),
None => (None, std::ptr::null_mut::<c_void>()),
}
}
pub(crate) fn get_su_callback<ClosureProto: ?Sized>(ptr: *mut c_void) -> Box<Box<ClosureProto>> {
assert!(!ptr.is_null());
unsafe { Box::from_raw(ptr as *mut Box<ClosureProto>) }
}
pub(crate) enum ListInstanceCallback<'a, ClosureProto: 'a + ?Sized> {
Entry(&'a mut Box<ClosureProto>),
End(Box<Box<ClosureProto>>),
Error(Box<Box<ClosureProto>>),
}
pub(crate) fn callback_for_list_instance<'a, ClosureProto: ?Sized>(eol: i32, ptr: *mut c_void
) -> ListInstanceCallback<'a, ClosureProto>
{
assert!(!ptr.is_null());
match eol {
0 => { let callback = unsafe { &mut *(ptr as *mut Box<ClosureProto>) };
ListInstanceCallback::Entry(callback)
},
i if i > 0 => { let mut callback = unsafe { Box::from_raw(ptr as *mut Box<ClosureProto>) };
ListInstanceCallback::End(callback)
},
_ => { let mut callback = unsafe { Box::from_raw(ptr as *mut Box<ClosureProto>) };
ListInstanceCallback::Error(callback)
},
}
}