1use libmtp_sys as ffi;
5
6#[derive(Debug, Copy, Clone)]
8pub enum CallbackReturn {
9 Continue,
11 Cancel,
13}
14
15#[allow(clippy::transmute_ptr_to_ref)]
16pub(crate) unsafe extern "C" fn progress_func_handler(
17 sent: u64,
18 total: u64,
19 data: *const libc::c_void,
20) -> libc::c_int {
21 let closure: &mut &mut dyn FnMut(u64, u64) -> CallbackReturn = std::mem::transmute(data);
22 match closure(sent, total) {
23 CallbackReturn::Continue => 0,
24 CallbackReturn::Cancel => 1,
25 }
26}
27
28#[derive(Debug, Copy, Clone)]
30pub enum HandlerReturn {
31 Ok(u32),
34
35 Error,
37
38 Cancel,
40}
41
42impl HandlerReturn {
43 pub(crate) fn is_error(&self) -> bool {
44 matches!(&self, HandlerReturn::Error)
45 }
46
47 pub(crate) fn is_cancel(&self) -> bool {
48 matches!(&self, HandlerReturn::Cancel)
49 }
50}
51
52#[allow(clippy::transmute_ptr_to_ref)]
53pub(crate) unsafe extern "C" fn data_put_func_handler(
54 _params: *mut libc::c_void,
55 private: *mut libc::c_void,
56 sendlen: u32,
57 data: *mut libc::c_uchar,
58 putlen: *mut u32,
59) -> u16 {
60 let (handler_return, closure): &mut (
61 &mut HandlerReturn,
62 &mut dyn FnMut(&[u8]) -> HandlerReturn,
63 ) = std::mem::transmute(private);
64
65 let data = prim_array_ptr_to_vec!(data, u8, sendlen);
66
67 **handler_return = closure(&data);
68 let ret = match **handler_return {
69 HandlerReturn::Ok(len) => {
70 *putlen = len;
72
73 ffi::LIBMTP_HANDLER_RETURN_OK
74 }
75
76 HandlerReturn::Error => ffi::LIBMTP_HANDLER_RETURN_ERROR,
77 HandlerReturn::Cancel => ffi::LIBMTP_HANDLER_RETURN_CANCEL,
78 };
79
80 ret as u16
81}
82
83#[allow(clippy::transmute_ptr_to_ref)]
84pub(crate) unsafe extern "C" fn data_get_func_handler(
85 _params: *mut libc::c_void,
86 private: *mut libc::c_void,
87 wantlen: u32,
88 data: *mut libc::c_uchar,
89 gotlen: *mut u32,
90) -> u16 {
91 let (handler_return, closure): &mut (
92 &mut HandlerReturn,
93 &mut dyn FnMut(&mut [u8]) -> HandlerReturn,
94 ) = std::mem::transmute(private);
95
96 let mut rsdata = vec![0 as u8; wantlen as usize];
97
98 **handler_return = closure(&mut rsdata);
99 let ret = match **handler_return {
100 HandlerReturn::Ok(len) => {
101 *gotlen = len;
103
104 libc::memcpy(
105 data as *mut _,
106 rsdata.as_ptr() as *const _,
107 wantlen as usize,
108 );
109
110 ffi::LIBMTP_HANDLER_RETURN_OK
111 }
112
113 HandlerReturn::Error => ffi::LIBMTP_HANDLER_RETURN_ERROR,
114 HandlerReturn::Cancel => ffi::LIBMTP_HANDLER_RETURN_CANCEL,
115 };
116
117 ret as u16
118}