#[macro_use] extern crate redis_module; #[macro_use] extern crate redismodule_cmd; use redis_module::{Context, RedisError, RedisResult, RedisValue}; use redismodule_cmd::{rediscmd_doc, ArgType, Collection, Command}; thread_local! { #[rediscmd_doc(clean)] static CMD: Command = command!{ name: "hello.foo", desc: "hello command example", args: [ ["input", "a string", ArgType::Arg, String, Collection::Unit, None], ["optional", "another string", ArgType::Arg, String, Collection::Unit, Some(Box::new("baz".to_owned()))], ["n", "some number", ArgType::Kwarg, u64, Collection::Unit, Some(Box::new(1_u64))], ["vec1", "a vector of ints", ArgType::Kwarg, i64, Collection::Vec, None], ], }; } fn hello_foo(_: &Context, args: Vec) -> RedisResult { let mut parsed = CMD.with(|cmd| cmd.parse_args(args))?; let input = parsed.remove("input").unwrap().as_string()?; let opt = parsed.remove("optional").unwrap().as_string()?; let n = parsed.remove("n").unwrap().as_u64()?; let vec1 = parsed.remove("vec1").unwrap().as_i64vec()?; let mut response: Vec = Vec::new(); for _ in 0..n { response.push(input.clone().into()); } response.push(opt.into()); response.push(vec1.iter().sum::().into()); return Ok(response.into()); } ////////////////////////////////////////////////////// redis_module! { name: "hello", version: 1, data_types: [], commands: [ ["hello.foo", hello_foo, "", 0, 0, 0], ], } ////////////////////////////////////////////////////// #[cfg(test)] mod tests { use super::*; use redis_module::RedisValue; fn run_hello_foo(args: &[&str]) -> RedisResult { hello_foo( &Context::dummy(), args.iter().map(|v| String::from(*v)).collect(), ) } #[test] fn hello_foo_valid_args() { let result = run_hello_foo(&vec![ "hello.foo", "bar", "n", "2", "vec1", "3", "1", "1", "1", ]); match result { Ok(RedisValue::Array(v)) => { let exp = vec![ RedisValue::BulkString("bar".to_owned()), RedisValue::BulkString("bar".to_owned()), RedisValue::BulkString("baz".to_owned()), RedisValue::Integer(3), ]; assert_eq!(v, exp); } _ => assert!(false, "Bad result: {:?}", result), } } #[test] fn hello_foo_invalid_args() { let result = run_hello_foo(&vec!["hello.foo", "n", "2", "3"]); match result { Err(RedisError::String(s)) => { assert_eq!(s, "Unexpected arg 3"); } _ => assert!(false, "Bad result: {:?}", result), } } #[test] fn hello_foo_invalid_cmd() { let result = run_hello_foo(&vec!["hello", "n", "2"]); match result { Err(RedisError::String(s)) => { assert_eq!(s, "Expected hello.foo, got hello"); } _ => assert!(false, "Bad result: {:?}", result), } let result = run_hello_foo(&vec!["hello.foo", "bar", "n", "2", "bad"]); match result { Err(RedisError::String(s)) => { assert_eq!(s, "Unexpected arg bad"); } _ => assert!(false, "Bad result: {:?}", result), } } }