1#[macro_use]
4extern crate redis_module;
5
6use redis_module::{alloc::RedisAlloc, Context, RedisError, RedisResult, RedisString, RedisValue};
7
8pub fn cas(ctx: &Context, args: Vec<RedisString>) -> RedisResult {
10 match args.as_slice() {
11 [_, key, current, new_value] => {
12 if let RedisValue::SimpleString(value) = ctx.call("GET", &[key.try_as_str()?])? {
13 if value.eq(¤t.try_as_str()?) {
14 let _ = ctx.call("SET", &[key.try_as_str()?, new_value.try_as_str()?])?;
15 return Ok(RedisValue::Integer(1));
16 }
17 }
18
19 Ok(RedisValue::Integer(0))
20 }
21 [_, key, current] => {
22 if let RedisValue::SimpleString(value) = ctx.call("GET", &[key.try_as_str()?])? {
23 if value.eq(¤t.try_as_str()?) {
24 let _ = ctx.call("DEL", &[key.try_as_str()?])?;
25 return Ok(RedisValue::Integer(1));
26 }
27 }
28
29 Ok(RedisValue::Integer(0))
30 }
31 _ => Err(RedisError::WrongArity),
32 }
33}
34
35redis_module! {
36 name: "redis_cas",
37 version: 1,
38 allocator: (RedisAlloc, RedisAlloc),
39 data_types: [],
40 commands: [
41 ["cas", cas, "write fast", 1, 1, 0],
42 ],
43}