@@ -136,59 +136,57 @@ where
136136 None ,
137137 )
138138}
139+ type ValueScalarCallbackWithAux < T > =
140+ fn ( * mut sqlite3_context , & [ * mut sqlite3_value ] , & mut T ) -> Result < ( ) > ;
141+ struct ScalarCallbackWithAux < T > {
142+ x_func : ValueScalarCallbackWithAux < T > ,
143+ aux : T ,
144+ }
139145
140146/// Defines a new scalar function, but with the added ability to pass in an arbritary
141147/// application "pointer" as any rust type. Can be accessed in the callback
142148/// function as the 3rd argument, as a reference.
143149/// <https://www.sqlite.org/c3ref/create_function.html#:~:text=The%20fifth%20parameter%20is%20an%20arbitrary%20pointer.>
144- pub fn define_scalar_function_with_aux < F , T > (
150+ pub fn define_scalar_function_with_aux < T > (
145151 db : * mut sqlite3 ,
146152 name : & str ,
147153 num_args : c_int ,
148- x_func : F ,
154+ x_func : ValueScalarCallbackWithAux < T > ,
149155 func_flags : FunctionFlags ,
150156 aux : T ,
151- ) -> Result < ( ) >
152- where
153- F : Fn ( * mut sqlite3_context , & [ * mut sqlite3_value ] , & T ) -> Result < ( ) > ,
154- {
155- let function_pointer: * mut F = Box :: into_raw ( Box :: new ( x_func) ) ;
156- let aux_pointer: * mut T = Box :: into_raw ( Box :: new ( aux) ) ;
157- let app_pointer = Box :: into_raw ( Box :: new ( ( function_pointer, aux_pointer) ) ) ;
157+ ) -> Result < ( ) > {
158+ let app_pointer = Box :: into_raw ( Box :: new ( ScalarCallbackWithAux { x_func, aux } ) ) ;
158159
159- unsafe extern "C" fn x_func_wrapper < F , T > (
160+ unsafe extern "C" fn x_func_wrapper < T > (
160161 context : * mut sqlite3_context ,
161162 argc : c_int ,
162163 argv : * mut * mut sqlite3_value ,
163- ) where
164- F : Fn ( * mut sqlite3_context , & [ * mut sqlite3_value ] , & T ) -> Result < ( ) > ,
165- {
166- let x = sqlite3ext_user_data ( context) . cast :: < ( * mut F , * mut T ) > ( ) ;
167- let boxed_function = ( * x) . 0 ;
168- let aux = ( * x) . 1 ;
169- // .collect slows things waaaay down, so stick with slice for now
164+ ) {
165+ let x = sqlite3ext_user_data ( context) . cast :: < ScalarCallbackWithAux < T > > ( ) ;
170166 let args = slice:: from_raw_parts ( argv, argc as usize ) ;
171- let b = Box :: from_raw ( aux) ;
172- match ( * boxed_function) ( context, args, & * b) {
167+ match ( ( * x) . x_func ) ( context, args, & mut ( * x) . aux ) {
173168 Ok ( ( ) ) => ( ) ,
174169 Err ( e) => {
175170 if api:: result_error ( context, & e. result_error_message ( ) ) . is_err ( ) {
176171 api:: result_error_code ( context, SQLITE_INTERNAL ) ;
177172 }
178173 }
179174 }
180- Box :: into_raw ( b) ;
175+ }
176+ unsafe extern "C" fn destroy < T > ( p_app : * mut c_void ) {
177+ let callbacks = p_app. cast :: < ScalarCallbackWithAux < T > > ( ) ;
178+ let _ = Box :: from_raw ( callbacks) ;
181179 }
182180 create_function_v2 (
183181 db,
184182 name,
185183 num_args,
186184 func_flags,
187185 app_pointer. cast :: < c_void > ( ) ,
188- Some ( x_func_wrapper :: < F , T > ) ,
189- None ,
186+ Some ( x_func_wrapper :: < T > ) ,
190187 None ,
191188 None ,
189+ Some ( destroy :: < T > ) ,
192190 )
193191}
194192
0 commit comments