Skip to content

Commit 7180e6b

Browse files
authored
Merge pull request #65 from RedisLabsModules/gavrie-is_keys_position_request
Add support for RedisModule_IsKeysPositionRequest
2 parents 9ea08ca + 98e7b17 commit 7180e6b

File tree

4 files changed

+45
-12
lines changed

4 files changed

+45
-12
lines changed

examples/hello.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
#[macro_use]
22
extern crate redis_module;
33

4-
use redis_module::{parse_integer, Context, RedisError, RedisResult};
4+
use redis_module::{parse_integer, Context, RedisError, RedisResult, RedisValue};
55

6-
fn hello_mul(_: &Context, args: Vec<String>) -> RedisResult {
6+
fn hello_mul(ctx: &Context, args: Vec<String>) -> RedisResult {
77
if args.len() < 2 {
88
return Err(RedisError::WrongArity);
99
}
1010

11+
if ctx.is_keys_position_request() {
12+
for i in 1..args.len() {
13+
if i % 2 == 0 {
14+
ctx.key_at_pos(i as i32);
15+
}
16+
}
17+
return Ok(RedisValue::NoReply);
18+
}
19+
1120
let nums = args
1221
.into_iter()
1322
.skip(1)
@@ -29,7 +38,7 @@ redis_module! {
2938
version: 1,
3039
data_types: [],
3140
commands: [
32-
["hello.mul", hello_mul, "", 1, 1, 1],
41+
["hello.mul", hello_mul, "getkeys-api", 1, 1, 1],
3342
],
3443
}
3544

src/context.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::ffi::CString;
2-
use std::os::raw::c_long;
2+
use std::os::raw::{c_long, c_int};
33
use std::ptr;
44

55
use crate::key::{RedisKey, RedisKeyWritable};
@@ -56,6 +56,22 @@ impl Context {
5656
}
5757
}
5858

59+
pub fn is_keys_position_request(&self) -> bool {
60+
let result = unsafe {
61+
raw::RedisModule_IsKeysPositionRequest.unwrap()(self.ctx)
62+
};
63+
64+
result != 0
65+
}
66+
67+
pub fn key_at_pos(&self, pos: i32) {
68+
// TODO: This will crash redis if `pos` is out of range.
69+
// Think of a way to make this safe by checking the range.
70+
unsafe {
71+
raw::RedisModule_KeyAtPos.unwrap()(self.ctx, pos as c_int);
72+
}
73+
}
74+
5975
pub fn call(&self, command: &str, args: &[&str]) -> RedisResult {
6076
let terminated_args: Vec<RedisString> = args
6177
.iter()
@@ -99,7 +115,7 @@ impl Context {
99115
}
100116
raw::ReplyType::Integer => Ok(RedisValue::Integer(raw::call_reply_integer(reply))),
101117
raw::ReplyType::String => Ok(RedisValue::SimpleString(raw::call_reply_string(reply))),
102-
raw::ReplyType::Nil => Ok(RedisValue::None),
118+
raw::ReplyType::Null => Ok(RedisValue::Null),
103119
}
104120
}
105121

@@ -145,12 +161,19 @@ impl Context {
145161
raw::Status::Ok
146162
}
147163

148-
Ok(RedisValue::None) => unsafe {
164+
Ok(RedisValue::Null) => unsafe {
149165
raw::RedisModule_ReplyWithNull.unwrap()(self.ctx).into()
150166
},
151167

168+
Ok(RedisValue::NoReply) => raw::Status::Ok,
169+
152170
Err(RedisError::WrongArity) => unsafe {
153-
raw::RedisModule_WrongArity.unwrap()(self.ctx).into()
171+
if self.is_keys_position_request() {
172+
// We can't return a result since we don't have a client
173+
raw::Status::Err
174+
} else {
175+
raw::RedisModule_WrongArity.unwrap()(self.ctx).into()
176+
}
154177
},
155178

156179
Err(RedisError::String(s)) => unsafe {

src/raw.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub enum ReplyType {
5959
Error = REDISMODULE_REPLY_ERROR_ISIZE,
6060
Integer = REDISMODULE_REPLY_INTEGER_ISIZE,
6161
Array = REDISMODULE_REPLY_ARRAY_ISIZE,
62-
Nil = REDISMODULE_REPLY_NULL_ISIZE,
62+
Null = REDISMODULE_REPLY_NULL_ISIZE,
6363
}
6464

6565
impl From<c_int> for ReplyType {

src/redisvalue.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ pub enum RedisValue {
66
Integer(i64),
77
Float(f64),
88
Array(Vec<RedisValue>),
9-
None,
9+
Null,
10+
NoReply, // No reply at all (as opposed to a Null reply)
1011
}
1112

1213
impl From<()> for RedisValue {
1314
fn from(_: ()) -> Self {
14-
RedisValue::None
15+
RedisValue::Null
1516
}
1617
}
1718

@@ -55,7 +56,7 @@ impl<T: Into<RedisValue>> From<Option<T>> for RedisValue {
5556
fn from(s: Option<T>) -> Self {
5657
match s {
5758
Some(v) => v.into(),
58-
None => RedisValue::None,
59+
None => RedisValue::Null,
5960
}
6061
}
6162
}
@@ -106,6 +107,6 @@ mod tests {
106107

107108
#[test]
108109
fn from_option_none() {
109-
assert_eq!(RedisValue::from(None::<()>), RedisValue::None,);
110+
assert_eq!(RedisValue::from(None::<()>), RedisValue::Null,);
110111
}
111112
}

0 commit comments

Comments
 (0)