use libmtp_sys as ffi;
#[derive(Debug, Copy, Clone)]
pub enum CallbackReturn {
Continue,
Cancel,
}
#[allow(clippy::transmute_ptr_to_ref)]
pub(crate) unsafe extern "C" fn progress_func_handler(
sent: u64,
total: u64,
data: *const libc::c_void,
) -> libc::c_int {
let closure: &mut &mut dyn FnMut(u64, u64) -> CallbackReturn = std::mem::transmute(data);
match closure(sent, total) {
CallbackReturn::Continue => 0,
CallbackReturn::Cancel => 1,
}
}
#[derive(Debug, Copy, Clone)]
pub enum HandlerReturn {
Ok(u32),
Error,
Cancel,
}
impl HandlerReturn {
pub(crate) fn is_error(&self) -> bool {
matches!(&self, HandlerReturn::Error)
}
pub(crate) fn is_cancel(&self) -> bool {
matches!(&self, HandlerReturn::Cancel)
}
}
#[allow(clippy::transmute_ptr_to_ref)]
pub(crate) unsafe extern "C" fn data_put_func_handler(
_params: *mut libc::c_void,
private: *mut libc::c_void,
sendlen: u32,
data: *mut libc::c_uchar,
putlen: *mut u32,
) -> u16 {
let (handler_return, closure): &mut (
&mut HandlerReturn,
&mut dyn FnMut(&[u8]) -> HandlerReturn,
) = std::mem::transmute(private);
let data = prim_array_ptr_to_vec!(data, u8, sendlen);
**handler_return = closure(&data);
let ret = match **handler_return {
HandlerReturn::Ok(len) => {
*putlen = len;
ffi::LIBMTP_HANDLER_RETURN_OK
}
HandlerReturn::Error => ffi::LIBMTP_HANDLER_RETURN_ERROR,
HandlerReturn::Cancel => ffi::LIBMTP_HANDLER_RETURN_CANCEL,
};
ret as u16
}
#[allow(clippy::transmute_ptr_to_ref)]
pub(crate) unsafe extern "C" fn data_get_func_handler(
_params: *mut libc::c_void,
private: *mut libc::c_void,
wantlen: u32,
data: *mut libc::c_uchar,
gotlen: *mut u32,
) -> u16 {
let (handler_return, closure): &mut (
&mut HandlerReturn,
&mut dyn FnMut(&mut [u8]) -> HandlerReturn,
) = std::mem::transmute(private);
let mut rsdata = vec![0 as u8; wantlen as usize];
**handler_return = closure(&mut rsdata);
let ret = match **handler_return {
HandlerReturn::Ok(len) => {
*gotlen = len;
libc::memcpy(
data as *mut _,
rsdata.as_ptr() as *const _,
wantlen as usize,
);
ffi::LIBMTP_HANDLER_RETURN_OK
}
HandlerReturn::Error => ffi::LIBMTP_HANDLER_RETURN_ERROR,
HandlerReturn::Cancel => ffi::LIBMTP_HANDLER_RETURN_CANCEL,
};
ret as u16
}