Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add RESP3 new APIs #280

Merged
merged 26 commits into from
Apr 5, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
66393c6
add RESP3 new APIs
gkorland Feb 8, 2023
abf94ae
handle Map, Set, Bool
gkorland Feb 8, 2023
8f3ddd4
add missing file
gkorland Feb 8, 2023
a4d462a
add clippy allow
gkorland Feb 8, 2023
5cc389f
fmt code
gkorland Feb 9, 2023
5d5417b
add example and test
gkorland Feb 9, 2023
3185635
add example
gkorland Feb 9, 2023
3a3c978
fix fail back case for array
gkorland Feb 9, 2023
18d4ac0
uncomment method compare
gkorland Feb 9, 2023
fca914b
Merge branch 'master' into gkorland-resp3-api
gkorland Feb 9, 2023
0bbe4aa
set uniqe port for the test
gkorland Feb 12, 2023
50b3e89
Merge branch 'master' into gkorland-resp3-api
gkorland Feb 12, 2023
70adf43
Merge branch 'master' into gkorland-resp3-api
MeirShpilraien Mar 23, 2023
7f44061
Added resp3 to CallReply and refactor CallReply to be more rusty
MeirShpilraien Mar 23, 2023
7d052ce
Added borrow API to CallReply. Document CallReply API.
MeirShpilraien Mar 24, 2023
b341954
Review fixes
MeirShpilraien Mar 25, 2023
071387c
Merge branch 'master' into gkorland-resp3-api
MeirShpilraien Mar 26, 2023
7feceec
Merge branch 'master' into gkorland-resp3-api
MeirShpilraien Mar 26, 2023
022b1be
Review fixes.
MeirShpilraien Mar 26, 2023
447f8ab
Merge branch 'master' into gkorland-resp3-api
MeirShpilraien Mar 26, 2023
83e020c
Review fixes.
MeirShpilraien Apr 2, 2023
674dbfa
Review fixes
MeirShpilraien Apr 4, 2023
f2f27e7
Use from_utf8_lossy on Display instead of printing NULL
MeirShpilraien Apr 5, 2023
d5e59eb
Format fixes.
MeirShpilraien Apr 5, 2023
84a8232
Review fixes.
MeirShpilraien Apr 5, 2023
c2395e8
Review fixes
MeirShpilraien Apr 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ crate-type = ["cdylib"]
name = "stream"
crate-type = ["cdylib"]

[[example]]
name = "response"
crate-type = ["cdylib"]

[dependencies]
bitflags = "1.2"
libc = "0.2"
Expand Down
51 changes: 42 additions & 9 deletions examples/call.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#[macro_use]
extern crate redis_module;

use redis_module::raw::*;
use redis_module::{
CallOptionsBuilder, CallReply, Context, RedisError, RedisResult, RedisString, RootCallReply,
CallOptionResp, CallOptionsBuilder, CallReply, CallResult, Context, RedisError, RedisResult,
RedisString,
};

fn call_test(ctx: &Context, _: Vec<RedisString>) -> RedisResult {
Expand Down Expand Up @@ -66,15 +66,48 @@ fn call_test(ctx: &Context, _: Vec<RedisString>) -> RedisResult {
}

let call_options = CallOptionsBuilder::new().script_mode().errors_as_replies();
let res: RootCallReply = ctx.call_ext::<&[&str; 0], _>("SHUTDOWN", &call_options.build(), &[]);
if res.get_type() != ReplyType::Error {
let res: CallResult = ctx.call_ext::<&[&str; 0], _>("SHUTDOWN", &call_options.build(), &[]);
if let Err(err) = res {
let error_msg = err.to_string().unwrap();
if !error_msg.contains("not allow") {
return Err(RedisError::String(format!(
"Failed to verify error messages, expected error message to contain 'not allow', error message: '{error_msg}'",
)));
}
} else {
iddm marked this conversation as resolved.
Show resolved Hide resolved
return Err(RedisError::Str("Failed to set script mode on call_ext"));
}
let error_msg = res.get_string().unwrap();
if !error_msg.contains("not allow") {
return Err(RedisError::String(format!(
"Failed to verify error messages, expected error message to contain 'not allow', error message: '{error_msg}'",
)));

// test resp3 on call_ext
let call_options = CallOptionsBuilder::new()
.script_mode()
.resp_3(CallOptionResp::Resp3)
.errors_as_replies()
.build();
ctx.call_ext::<_, CallResult>("HSET", &call_options, &["x", "foo", "bar"])
.map_err(|e| -> RedisError { e.into() })?;
let res: CallReply = ctx
.call_ext::<_, CallResult>("HGETALL", &call_options, &["x"])
.map_err(|e| -> RedisError { e.into() })?;
if let CallReply::Map(map) = res {
let res = map.iter().fold(Vec::new(), |mut vec, (key, val)| {
if let CallReply::String(key) = key.unwrap() {
vec.push(key.to_string().unwrap());
}
if let CallReply::String(val) = val.unwrap() {
vec.push(val.to_string().unwrap());
}
vec
});
if res != vec!["foo".to_string(), "bar".to_string()] {
return Err(RedisError::String(
"Reply of hgetall does not match expected value".into(),
));
}
} else {
return Err(RedisError::String(
"Did not get a set type on hgetall".into(),
));
}

Ok("pass".into())
Expand Down
72 changes: 72 additions & 0 deletions examples/response.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#[macro_use]
extern crate redis_module;

use redis_module::{Context, NextArg, RedisError, RedisResult, RedisString, RedisValue};
use std::collections::{HashMap, HashSet};

fn map_mget(ctx: &Context, args: Vec<RedisString>) -> RedisResult {
MeirShpilraien marked this conversation as resolved.
Show resolved Hide resolved
if args.len() < 2 {
return Err(RedisError::WrongArity);
}

let mut args = args.into_iter().skip(1);
let key_name = args.next_arg()?;

let fields: Vec<RedisString> = args.collect();

let key = ctx.open_key(&key_name);
let values = key.hash_get_multi(&fields)?;
let res = match values {
None => RedisValue::Null,
iddm marked this conversation as resolved.
Show resolved Hide resolved
Some(values) => {
let mut map: HashMap<RedisValue, RedisValue> = HashMap::with_capacity(fields.len());
for (field, value) in values.into_iter() {
map.insert(
RedisValue::BulkRedisString(field),
RedisValue::BulkRedisString(value),
);
}
RedisValue::Map(map)
}
};

Ok(res)
}

fn map_unique(ctx: &Context, args: Vec<RedisString>) -> RedisResult {
if args.len() < 2 {
return Err(RedisError::WrongArity);
}

let mut args = args.into_iter().skip(1);
let key_name = args.next_arg()?;

let fields: Vec<RedisString> = args.collect();

let key = ctx.open_key(&key_name);
let values = key.hash_get_multi(&fields)?;
let res = match values {
None => RedisValue::Null,
Some(values) => {
let mut set: HashSet<RedisValue> = HashSet::new();
for (_, value) in values.into_iter() {
set.insert(RedisValue::BulkRedisString(value));
}
RedisValue::Set(set)
}
};

Ok(res)
}

//////////////////////////////////////////////////////

redis_module! {
name: "response",
version: 1,
data_types: [],
commands: [
["map.mget", map_mget, "readonly", 1, 1, 1],
["map.unique", map_unique, "readonly", 1, 1, 1],
],
}
4 changes: 2 additions & 2 deletions examples/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ redis_module! {
version: 1,
data_types: [],
commands: [
["string.set", string_set, "", 1, 1, 1],
["string.get", string_get, "", 1, 1, 1],
["string.set", string_set, "write fast deny-oom", 1, 1, 1],
["string.get", string_get, "readonly", 1, 1, 1],
],
}
Loading