Skip to content
This repository was archived by the owner on Apr 20, 2020. It is now read-only.

Commit 19e86d7

Browse files
committed
Adapt to latest version of redismodule-rs
1 parent a8f065d commit 19e86d7

File tree

2 files changed

+40
-191
lines changed

2 files changed

+40
-191
lines changed

src/lib.rs

Lines changed: 37 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -1,212 +1,60 @@
1-
use std::os::raw::c_void;
2-
3-
extern crate libc;
4-
5-
use libc::c_int;
6-
1+
#[macro_use]
72
extern crate redismodule;
83

9-
use redismodule::error::Error;
10-
use redismodule::Command;
11-
use redismodule::raw;
12-
use redismodule::Redis;
13-
use redismodule::raw::module_init;
14-
use redismodule::types::RedisType;
4+
use redismodule::{Context, RedisResult, NextArg};
5+
use redismodule::native_types::RedisType;
156

167
mod redisdoc;
178

18-
const MODULE_NAME: &str = "redisdoc";
19-
const MODULE_VERSION: c_int = 1;
20-
21-
static DOC_TYPE: RedisType = RedisType::new();
9+
use crate::redisdoc::RedisDoc;
2210

23-
struct DocSetCommand;
11+
static DOC_REDIS_TYPE: RedisType = RedisType::new("RedisDoc1");
2412

25-
impl Command for DocSetCommand {
26-
fn name() -> &'static str { "doc.set" }
13+
fn doc_set(ctx: &Context, args: Vec<String>) -> RedisResult {
14+
let mut args = args.into_iter().skip(1);
2715

28-
fn external_command() -> raw::CommandFunc { DocSetCommand_Redis }
16+
let key = args.next_string()?;
17+
let value = args.next_string()?;
2918

30-
fn str_flags() -> &'static str { "write" }
19+
let key = ctx.open_key_writable(&key);
3120

32-
// Run the command.
33-
fn run(r: Redis, args: &[&str]) -> Result<(), Error> {
34-
if args.len() != 3 {
35-
// FIXME: Use RedisModule_WrongArity instead. Return an ArityError here and
36-
// in the low-level implementation call RM_WrongArity.
37-
return Err(Error::generic(format!(
38-
"Usage: {} <key> <size>", Self::name()
39-
).as_str()));
21+
match key.get_value::<RedisDoc>(&DOC_REDIS_TYPE)? {
22+
Some(doc) => {
23+
doc.set_value(&value)?;
4024
}
41-
42-
// the first argument is command name (ignore it)
43-
let key = args[1];
44-
let value = args[2];
45-
46-
let key = r.open_key_writable(key);
47-
let key_type = key.verify_and_get_type(&DOC_TYPE)?;
48-
49-
let my = match key_type {
50-
raw::KeyType::Empty => {
51-
Box::new(
52-
redisdoc::RedisDoc::from_str(value)?
53-
)
54-
}
55-
_ => {
56-
// There is an existing value, reuse it
57-
let my = key.get_value() as *mut redisdoc::RedisDoc;
58-
59-
if my.is_null() {
60-
r.reply_integer(0)?;
61-
return Ok(());
62-
}
63-
64-
let mut my = unsafe { Box::from_raw(my) };
65-
my.set_value(value)?;
66-
my
67-
}
68-
};
69-
70-
let my = Box::into_raw(my);
71-
72-
key.set_value(&DOC_TYPE, my as *mut c_void)?;
73-
74-
let size = 0; // TODO: Calc size
75-
r.reply_integer(size)?;
76-
77-
Ok(())
78-
}
79-
}
80-
81-
#[allow(non_snake_case)]
82-
pub extern "C" fn DocSetCommand_Redis(
83-
ctx: *mut raw::RedisModuleCtx,
84-
argv: *mut *mut raw::RedisModuleString,
85-
argc: c_int,
86-
) -> c_int {
87-
DocSetCommand::execute(ctx, argv, argc).into()
88-
}
89-
90-
//////////////////////////////////////////////////////
91-
92-
struct DocGetCommand;
93-
94-
impl Command for DocGetCommand {
95-
fn name() -> &'static str { "doc.get" }
96-
97-
fn external_command() -> raw::CommandFunc { DocGetCommand_Redis }
98-
99-
fn str_flags() -> &'static str { "" }
100-
101-
// Run the command.
102-
fn run(r: Redis, args: &[&str]) -> Result<(), Error> {
103-
if args.len() != 2 {
104-
// FIXME: Use RedisModule_WrongArity instead. Return an ArityError here and
105-
// in the low-level implementation call RM_WrongArity.
106-
return Err(Error::generic(format!(
107-
"Usage: {} <key>", Self::name()
108-
).as_str()));
25+
None => {
26+
let doc = RedisDoc::from_str(&value)?;
27+
key.set_value(&DOC_REDIS_TYPE, doc)?;
10928
}
110-
111-
// the first argument is command name (ignore it)
112-
let key = args[1];
113-
114-
let key = r.open_key(key);
115-
key.verify_and_get_type(&DOC_TYPE)?;
116-
let my = key.get_value() as *mut redisdoc::RedisDoc;
117-
118-
if my.is_null() {
119-
r.reply_integer(0)?;
120-
return Ok(());
121-
}
122-
123-
let my = unsafe { &mut *my };
124-
let size = 42; // TODO // my.data.len();
125-
126-
r.reply_array(2)?;
127-
r.reply_integer(size as i64)?;
128-
r.reply_string(my.to_string()?.as_str())?;
129-
130-
Ok(())
13129
}
132-
}
13330

134-
#[allow(non_snake_case)]
135-
pub extern "C" fn DocGetCommand_Redis(
136-
ctx: *mut raw::RedisModuleCtx,
137-
argv: *mut *mut raw::RedisModuleString,
138-
argc: c_int,
139-
) -> c_int {
140-
DocGetCommand::execute(ctx, argv, argc).into()
31+
Ok(().into())
14132
}
14233

143-
//////////////////////////////////////////////////////
144-
145-
struct DocDelCommand;
146-
147-
impl Command for DocDelCommand {
148-
fn name() -> &'static str { "doc.del" }
149-
150-
fn external_command() -> raw::CommandFunc { DocDelCommand_Redis }
151-
152-
fn str_flags() -> &'static str { "write" }
153-
154-
// Run the command.
155-
fn run(r: Redis, args: &[&str]) -> Result<(), Error> {
156-
if args.len() != 2 {
157-
// FIXME: Use RedisModule_WrongArity instead?
158-
return Err(Error::generic(format!(
159-
"Usage: {} <key>", Self::name()
160-
).as_str()));
161-
}
34+
fn doc_get(ctx: &Context, args: Vec<String>) -> RedisResult {
35+
let mut args = args.into_iter().skip(1);
36+
let key = args.next_string()?;
16237

163-
// the first argument is command name (ignore it)
164-
let _key = args[1];
38+
let key = ctx.open_key_writable(&key);
16539

166-
r.reply_string("OK")?;
40+
let value = match key.get_value::<RedisDoc>(&DOC_REDIS_TYPE)? {
41+
Some(doc) => { doc.to_string()?.into() }
42+
None => ().into()
43+
};
16744

168-
Ok(())
169-
}
170-
}
171-
172-
// TODO: Write a macro to generate these glue functions
173-
// TODO: Look at https://github.com/faineance/redismodule which has some macros
174-
175-
#[allow(non_snake_case)]
176-
pub extern "C" fn DocDelCommand_Redis(
177-
ctx: *mut raw::RedisModuleCtx,
178-
argv: *mut *mut raw::RedisModuleString,
179-
argc: c_int,
180-
) -> c_int {
181-
DocDelCommand::execute(ctx, argv, argc).into()
182-
}
183-
184-
fn module_on_load(ctx: *mut raw::RedisModuleCtx) -> Result<(), &'static str> {
185-
module_init(ctx, MODULE_NAME, MODULE_VERSION)?;
186-
187-
// TODO: Call this from inside module_init
188-
redismodule::use_redis_alloc();
189-
190-
DOC_TYPE.create_data_type(ctx, "RedisDoc1")?;
191-
192-
DocSetCommand::create(ctx)?;
193-
DocGetCommand::create(ctx)?;
194-
DocDelCommand::create(ctx)?;
195-
196-
Ok(())
45+
Ok(value)
19746
}
19847

199-
#[allow(non_snake_case)]
200-
#[no_mangle]
201-
pub extern "C" fn RedisModule_OnLoad(
202-
ctx: *mut raw::RedisModuleCtx,
203-
_argv: *mut *mut raw::RedisModuleString,
204-
_argc: c_int,
205-
) -> c_int {
206-
if let Err(msg) = module_on_load(ctx) {
207-
eprintln!("Error loading module: {}", msg);
208-
return raw::Status::Err.into();
209-
}
48+
//////////////////////////////////////////////////////
21049

211-
raw::Status::Ok.into()
50+
redis_module! {
51+
name: "redisdoc",
52+
version: 1,
53+
data_types: [
54+
DOC_REDIS_TYPE,
55+
],
56+
commands: [
57+
["doc.set", doc_set, "write"],
58+
["doc.get", doc_get, ""],
59+
],
21260
}

src/redisdoc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ impl From<serde_json::Error> for Error {
1616
}
1717
}
1818

19-
impl From<Error> for redismodule::error::Error {
19+
impl From<Error> for redismodule::RedisError {
2020
fn from(e: Error) -> Self {
21-
redismodule::error::Error::generic(e.msg.as_str())
21+
redismodule::RedisError::String(e.msg)
2222
}
2323
}
2424

25+
#[derive(Debug)]
2526
pub struct RedisDoc {
2627
data: Value,
2728
}

0 commit comments

Comments
 (0)