@@ -7,7 +7,7 @@ use crate::{key::RedisKey, raw, RedisString};
77
88/// A cursor to scan field/value pairs of a (hash) key.
99///
10- /// It provides access via a closure given to [`ScanKeyCursor::for_each`] or if you need more control, you can use [`ScanKeyCursor::scan`]
10+ /// It provides access via a closure given to [`ScanKeyCursor::for_each`] or if you need more control, you can use [`ScanKeyCursor::scan`]
1111/// and implement your own loop, e.g. to allow an early stop.
1212///
1313/// ## Example usage
@@ -64,8 +64,34 @@ impl ScanKeyCursor {
6464 }
6565
6666 pub fn scan < F : FnMut ( & RedisKey , & RedisString , & RedisString ) > ( & self , f : F ) -> bool {
67- // the following is the callback definition. The callback may be called multiple times per `RedisModule_ScanKey` invocation.
68- use pimpl:: scan_callback;
67+ // The following is the callback definition. The callback may be called multiple times per `RedisModule_ScanKey` invocation.
68+ // The callback is used by [`ScanKeyCursor::scan`] and [`ScanKeyCursor::for_each`] as argument to `RedisModule_ScanKey`.
69+ //
70+ // The `data` pointer is the closure given to [`ScanKeyCursor::scan`] or [`ScanKeyCursor::for_each`].
71+ // The callback forwards references to the key, field and value to that closure.
72+ unsafe extern "C" fn scan_callback <
73+ F : FnMut ( & RedisKey , & RedisString , & RedisString ) ,
74+ > (
75+ key : * mut raw:: RedisModuleKey ,
76+ field : * mut raw:: RedisModuleString ,
77+ value : * mut raw:: RedisModuleString ,
78+ data : * mut c_void ,
79+ ) {
80+ let ctx = ptr:: null_mut ( ) ;
81+ let key = RedisKey :: from_raw_parts ( ctx, key) ;
82+
83+ let field = RedisString :: from_redis_module_string ( ctx, field) ;
84+ let value = RedisString :: from_redis_module_string ( ctx, value) ;
85+
86+ let callback = unsafe { & mut * ( data. cast :: < F > ( ) ) } ;
87+ callback ( & key, & field, & value) ;
88+
89+ // we're not the owner of field and value strings
90+ field. take ( ) ;
91+ value. take ( ) ;
92+
93+ key. take ( ) ; // we're not the owner of the key either
94+ }
6995
7096 // Safety: The c-side initialized the function ptr and it is is never changed,
7197 // i.e. after module initialization the function pointers stay valid till the end of the program.
@@ -94,36 +120,3 @@ impl Drop for ScanKeyCursor {
94120 unsafe { raw:: RedisModule_ScanCursorDestroy . unwrap ( ) ( self . inner_cursor ) } ;
95121 }
96122}
97-
98- // the module contains the private implementation details of the cursor.
99- mod pimpl {
100- use super :: * ;
101-
102- /// The callback that is used by [`ScanKeyCursor::scan`] and [`ScanKeyCursor::for_each`] as argument to `RedisModule_ScanKey`.
103- ///
104- /// The `data` pointer is the closure given to [`ScanKeyCursor::for_each`] and the callback forwards
105- /// references to the key, field and value to that closure.
106- pub ( super ) unsafe extern "C" fn scan_callback <
107- F : FnMut ( & RedisKey , & RedisString , & RedisString ) ,
108- > (
109- key : * mut raw:: RedisModuleKey ,
110- field : * mut raw:: RedisModuleString ,
111- value : * mut raw:: RedisModuleString ,
112- data : * mut c_void ,
113- ) {
114- let ctx = ptr:: null_mut ( ) ;
115- let key = RedisKey :: from_raw_parts ( ctx, key) ;
116-
117- let field = RedisString :: from_redis_module_string ( ctx, field) ;
118- let value = RedisString :: from_redis_module_string ( ctx, value) ;
119-
120- let callback = unsafe { & mut * ( data. cast :: < F > ( ) ) } ;
121- callback ( & key, & field, & value) ;
122-
123- // we're not the owner of field and value strings
124- field. take ( ) ;
125- value. take ( ) ;
126-
127- key. take ( ) ; // we're not the owner of the key either
128- }
129- }
0 commit comments