|
1 | 1 | use itertools::Itertools; |
2 | | -use redis_module::{Context, NextArg, RedisError, RedisResult, RedisString, RedisValue}; |
| 2 | +use redis_module::{Context, RedisError, RedisResult, RedisString, RedisValue}; |
| 3 | + |
| 4 | +use super::redis_module_ext::call; |
3 | 5 |
|
4 | 6 | /// ZUNIONBYSCORE numkeys key [key ...] min max [LIMIT] offset count |
5 | 7 | pub fn zunionbyscore(ctx: &Context, args: Vec<RedisString>) -> RedisResult { |
6 | 8 | if args.len() < 8 { |
7 | 9 | return Err(RedisError::WrongArity); |
8 | 10 | } |
9 | 11 |
|
10 | | - let mut mutable_args = args.into_iter().skip(1); |
11 | | - let numkeys = mutable_args.next_i64()?; |
12 | | - let numkeys_string = numkeys.to_string(); |
| 12 | + let mut args_iter = args.iter().skip(1); |
| 13 | + let numkeys_str = args_iter.next().ok_or(RedisError::WrongArity)?; |
| 14 | + let numkeys = numkeys_str |
| 15 | + .parse_integer() |
| 16 | + .map_err(|_| RedisError::WrongArity)?; |
13 | 17 |
|
14 | | - let mut keys: Vec<&str> = Vec::new(); |
15 | | - keys.push(&numkeys_string); |
| 18 | + let keys = &args[2..(2 + numkeys as usize)]; |
| 19 | + let min_arg = &args[2 + numkeys as usize]; |
| 20 | + let max_arg = &args[3 + numkeys as usize]; |
| 21 | + let limit_arg = &args[4 + numkeys as usize]; |
| 22 | + let offset_arg = &args[5 + numkeys as usize]; |
| 23 | + let count_arg = &args[6 + numkeys as usize]; |
16 | 24 |
|
17 | | - for _i in 0..numkeys { |
18 | | - let key = mutable_args.next_str()?; |
19 | | - keys.push(key); |
| 25 | + if limit_arg.to_string_lossy() != "LIMIT" { |
| 26 | + return Err(RedisError::WrongType); |
20 | 27 | } |
21 | 28 |
|
22 | | - let min = mutable_args.next_f64()?; |
23 | | - let max = mutable_args.next_f64()?; |
| 29 | + let min = min_arg.parse_float().map_err(|_| RedisError::WrongType)?; |
| 30 | + let max = max_arg.parse_float().map_err(|_| RedisError::WrongType)?; |
24 | 31 |
|
25 | | - let limit = mutable_args.next_str()?; |
26 | | - if limit != "LIMIT" { |
27 | | - return Err(RedisError::WrongArity); |
28 | | - } |
| 32 | + let offset = offset_arg |
| 33 | + .parse_unsigned_integer() |
| 34 | + .map_err(|_| RedisError::WrongType)?; |
| 35 | + let count = count_arg |
| 36 | + .parse_unsigned_integer() |
| 37 | + .map_err(|_| RedisError::WrongType)?; |
29 | 38 |
|
30 | | - let offset = mutable_args.next_u64()?; |
31 | | - let count = mutable_args.next_u64()?; |
| 39 | + let min_str = min.to_string(); |
| 40 | + let max_str = max.to_string(); |
| 41 | + let byscore = ctx.create_string("BYSCORE"); |
| 42 | + let withscores = ctx.create_string("WITHSCORES"); |
| 43 | + let min_redis_str = ctx.create_string(&min_str); |
| 44 | + let max_redis_str = ctx.create_string(&max_str); |
32 | 45 |
|
33 | 46 | let response = keys |
34 | | - .into_iter() |
| 47 | + .iter() |
35 | 48 | .filter_map(|key| { |
36 | | - let min_str = min.to_string(); |
37 | | - let max_str = max.to_string(); |
38 | | - |
39 | | - let results = ctx |
40 | | - .call( |
41 | | - "zrange", |
42 | | - &[key, &min_str, &max_str, "BYSCORE", "WITHSCORES"], |
43 | | - ) |
44 | | - .ok()?; |
| 49 | + let results = call( |
| 50 | + ctx, |
| 51 | + "zrange", |
| 52 | + &[key, &min_redis_str, &max_redis_str, &byscore, &withscores], |
| 53 | + ) |
| 54 | + .ok()?; |
45 | 55 | match results { |
46 | 56 | RedisValue::Array(values) => { |
47 | 57 | let keys = values |
|
0 commit comments