Skip to content

Commit af85a30

Browse files
committed
move callback into function body
1 parent 406899d commit af85a30

File tree

1 file changed

+29
-36
lines changed

1 file changed

+29
-36
lines changed

src/context/key_cursor.rs

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)