@@ -6,6 +6,10 @@ use std::ffi::CString;
66use std:: os:: raw:: { c_char, c_int, c_long, c_longlong} ;
77
88extern crate libc;
9+ extern crate enum_primitive_derive;
10+ extern crate num_traits;
11+
12+ use num_traits:: { FromPrimitive , ToPrimitive } ;
913
1014use libc:: size_t;
1115
@@ -18,64 +22,53 @@ bitflags! {
1822 }
1923}
2024
25+ #[ derive( Primitive ) ]
26+ pub enum KeyType {
27+ Empty = REDISMODULE_KEYTYPE_EMPTY as isize ,
28+ String = REDISMODULE_KEYTYPE_STRING as isize ,
29+ List = REDISMODULE_KEYTYPE_LIST as isize ,
30+ Hash = REDISMODULE_KEYTYPE_HASH as isize ,
31+ Set = REDISMODULE_KEYTYPE_SET as isize ,
32+ ZSet = REDISMODULE_KEYTYPE_ZSET as isize ,
33+ Module = REDISMODULE_KEYTYPE_MODULE as isize ,
34+ }
35+
36+ impl From < c_int > for KeyType {
37+ fn from ( v : c_int ) -> Self { KeyType :: from_i32 ( v) . unwrap ( ) }
38+ }
2139
22- #[ derive( Debug , PartialEq ) ]
23- #[ repr( i32 ) ]
40+ // This hack is required since derive(Primitive) requires all values to have the same type,
41+ // and REDISMODULE_REPLY_UNKNOWN is i32 while the rest are u32.
42+ // Casting to isize inside the enum definition breaks the derive(Primitive) macro.
43+ const REDISMODULE_REPLY_UNKNOWN_ISIZE : isize = REDISMODULE_REPLY_UNKNOWN as isize ;
44+ const REDISMODULE_REPLY_STRING_ISIZE : isize = REDISMODULE_REPLY_STRING as isize ;
45+ const REDISMODULE_REPLY_ERROR_ISIZE : isize = REDISMODULE_REPLY_ERROR as isize ;
46+ const REDISMODULE_REPLY_INTEGER_ISIZE : isize = REDISMODULE_REPLY_INTEGER as isize ;
47+ const REDISMODULE_REPLY_ARRAY_ISIZE : isize = REDISMODULE_REPLY_ARRAY as isize ;
48+ const REDISMODULE_REPLY_NULL_ISIZE : isize = REDISMODULE_REPLY_NULL as isize ;
49+
50+ #[ derive( Primitive , Debug , PartialEq ) ]
2451pub enum ReplyType {
25- Unknown = REDISMODULE_REPLY_UNKNOWN as i32 ,
26- String = REDISMODULE_REPLY_STRING as i32 ,
27- Error = REDISMODULE_REPLY_ERROR as i32 ,
28- Integer = REDISMODULE_REPLY_INTEGER as i32 ,
29- Array = REDISMODULE_REPLY_ARRAY as i32 ,
30- Nil = REDISMODULE_REPLY_NULL as i32 ,
31- }
32-
33- // Tools that can automate this:
34- // https://crates.io/crates/enum_primitive
35- // https://crates.io/crates/num_enum
36- // https://crates.io/crates/enum-primitive-derive
37-
38- impl From < i32 > for ReplyType {
39- fn from ( v : i32 ) -> Self {
40- use crate :: raw:: ReplyType :: * ;
41-
42- // TODO: Is there a way to do this with a `match`? We have different types of constants here.
43- if v == Unknown as i32 {
44- Unknown
45- } else if v == String as i32 {
46- String
47- } else if v == Error as i32 {
48- Error
49- } else if v == Integer as i32 {
50- Integer
51- } else if v == Array as i32 {
52- Array
53- } else if v == Nil as i32 {
54- Nil
55- } else {
56- panic ! ( "Received unexpected reply type from Redis: {}" , v)
57- }
58- }
52+ Unknown = REDISMODULE_REPLY_UNKNOWN_ISIZE ,
53+ String = REDISMODULE_REPLY_STRING_ISIZE ,
54+ Error = REDISMODULE_REPLY_ERROR_ISIZE ,
55+ Integer = REDISMODULE_REPLY_INTEGER_ISIZE ,
56+ Array = REDISMODULE_REPLY_ARRAY_ISIZE ,
57+ Nil = REDISMODULE_REPLY_NULL_ISIZE ,
5958}
6059
61- #[ derive( Clone , Copy , Debug , PartialEq ) ]
62- #[ repr( i32 ) ]
60+ impl From < c_int > for ReplyType {
61+ fn from ( v : c_int ) -> Self { ReplyType :: from_i32 ( v) . unwrap ( ) }
62+ }
63+
64+ #[ derive( Primitive , Debug , PartialEq ) ]
6365pub enum Status {
64- Ok = REDISMODULE_OK as i32 ,
65- Err = REDISMODULE_ERR as i32 ,
66+ Ok = REDISMODULE_OK as isize ,
67+ Err = REDISMODULE_ERR as isize ,
6668}
6769
6870impl From < c_int > for Status {
69- fn from ( v : c_int ) -> Self {
70- // TODO: Is there a way to do this with a `match`? We have different types of constants here.
71- if v == REDISMODULE_OK as c_int {
72- Status :: Ok
73- } else if v == REDISMODULE_ERR as c_int {
74- Status :: Err
75- } else {
76- panic ! ( "Received unexpected status from Redis: {}" , v)
77- }
78- }
71+ fn from ( v : c_int ) -> Self { Status :: from_i32 ( v) . unwrap ( ) }
7972}
8073
8174impl From < Status > for c_int {
@@ -93,6 +86,47 @@ impl From<Status> for Result<(), &str> {
9386 }
9487}
9588
89+
90+ #[ derive( Debug ) ]
91+ pub enum CommandFlag {
92+ Write ,
93+ Readonly ,
94+ Denyoom ,
95+ Admin ,
96+ Pubsub ,
97+ Noscript ,
98+ Random ,
99+ SortForScript ,
100+ Loading ,
101+ Stale ,
102+ SkipMonitor ,
103+ Asking ,
104+ Fast ,
105+ Movablekeys ,
106+ }
107+
108+
109+ fn command_flag_repr ( flag : & CommandFlag ) -> & ' static str {
110+ use crate :: raw:: CommandFlag :: * ;
111+ match flag {
112+ Write => "write" ,
113+ Readonly => "readonly" ,
114+ Denyoom => "denyoom" ,
115+ Admin => "admin" ,
116+ Pubsub => "pubsub" ,
117+ Noscript => "noscript" ,
118+ Random => "random" ,
119+ SortForScript => "sort_for_script" ,
120+ Loading => "loading" ,
121+ Stale => "stale" ,
122+ SkipMonitor => "skip_monitor" ,
123+ Asking => "asking" ,
124+ Fast => "fast" ,
125+ Movablekeys => "movablekeys" ,
126+ }
127+ }
128+
129+
96130pub type CommandFunc = extern "C" fn (
97131 ctx : * mut RedisModuleCtx ,
98132 argv : * mut * mut RedisModuleString ,
@@ -120,8 +154,8 @@ pub fn create_command(
120154 firstkey,
121155 lastkey,
122156 keystep,
123- ) . into ( )
124- } ;
157+ )
158+ } . into ( ) ;
125159
126160 status. into ( )
127161}
@@ -160,9 +194,7 @@ extern "C" {
160194
161195///////////////////////////////////////////////////////////////
162196
163-
164197// Helper functions for the raw bindings.
165- // Taken from redis-cell.
166198
167199pub fn call_reply_type ( reply : * mut RedisModuleCallReply ) -> ReplyType {
168200 unsafe {
@@ -270,3 +302,7 @@ pub fn string_ptr_len(str: *mut RedisModuleString, len: *mut size_t) -> *const c
270302pub fn string_set ( key : * mut RedisModuleKey , str : * mut RedisModuleString ) -> Status {
271303 unsafe { RedisModule_StringSet . unwrap ( ) ( key, str) . into ( ) }
272304}
305+
306+ pub fn key_type ( key : * mut RedisModuleKey ) -> KeyType {
307+ unsafe { RedisModule_KeyType . unwrap ( ) ( key) } . into ( )
308+ }
0 commit comments