11#[ macro_use]
22extern crate redismodule;
33
4- use redismodule:: { Context , RedisResult , NextArg , REDIS_OK } ;
4+ use redismodule:: { Context , RedisResult , NextArg , REDIS_OK , RedisError } ;
55use redismodule:: native_types:: RedisType ;
66
77mod redisjson;
@@ -10,26 +10,45 @@ use crate::redisjson::RedisJSON;
1010
1111static REDIS_JSON_TYPE : RedisType = RedisType :: new ( "RedisJSON" ) ;
1212
13+ #[ derive( Debug , PartialEq ) ]
14+ pub enum SetOptions {
15+ NotExists ,
16+ AlreadyExists ,
17+ }
18+
1319fn json_set ( ctx : & Context , args : Vec < String > ) -> RedisResult {
1420 let mut args = args. into_iter ( ) . skip ( 1 ) ;
1521
1622 let key = args. next_string ( ) ?;
1723 let _path = args. next_string ( ) ?; // TODO handle this path
1824 let value = args. next_string ( ) ?;
1925
26+ let set_option = args. next ( )
27+ . map ( |op| {
28+ match op. to_uppercase ( ) . as_str ( ) {
29+ "NX" => Ok ( SetOptions :: NotExists ) ,
30+ "XX" => Ok ( SetOptions :: AlreadyExists ) ,
31+ _ => Err ( RedisError :: Str ( "ERR syntax error" ) ) ,
32+ }
33+ } )
34+ . transpose ( ) ?;
35+
2036 let key = ctx. open_key_writable ( & key) ;
37+ let current = key. get_value :: < RedisJSON > ( & REDIS_JSON_TYPE ) ?;
2138
22- match key. get_value :: < RedisJSON > ( & REDIS_JSON_TYPE ) ? {
23- Some ( doc) => {
39+ match ( current, set_option) {
40+ ( Some ( _) , Some ( SetOptions :: NotExists ) ) => Ok ( ( ) . into ( ) ) ,
41+ ( Some ( ref mut doc) , _) => {
2442 doc. set_value ( & value) ?;
43+ REDIS_OK
2544 }
26- None => {
45+ ( None , Some ( SetOptions :: AlreadyExists ) ) => Ok ( ( ) . into ( ) ) ,
46+ ( None , _) => {
2747 let doc = RedisJSON :: from_str ( & value) ?;
2848 key. set_value ( & REDIS_JSON_TYPE , doc) ?;
49+ REDIS_OK
2950 }
3051 }
31-
32- REDIS_OK
3352}
3453
3554fn json_get ( ctx : & Context , args : Vec < String > ) -> RedisResult {
0 commit comments