Skip to main content

kevy_client_async/
cmd_zset.rs

1//! Async mirror of sorted-set commands on `kevy_client::Connection`.
2
3use std::io;
4
5use kevy_resp::Reply;
6
7use crate::cmd_set::set_multi;
8use crate::conn::AsyncConnection;
9use crate::reply::{array_to_bulks, string, unexpected, vec2, vec3};
10
11impl AsyncConnection {
12    /// `ZADD key score member [score member ...]`. Returns count of
13    /// newly added (overwrites don't count).
14    pub async fn zadd(&mut self, key: &[u8], pairs: &[(f64, &[u8])]) -> io::Result<usize> {
15        let mut args = Vec::with_capacity(2 + pairs.len() * 2);
16        args.push(b"ZADD".to_vec());
17        args.push(key.to_vec());
18        for (score, m) in pairs {
19            args.push(score.to_string().into_bytes());
20            args.push(m.to_vec());
21        }
22        match self.codec_mut().request(&args).await? {
23            Reply::Int(n) if n >= 0 => Ok(n as usize),
24            Reply::Error(e) => Err(io::Error::other(string(e))),
25            other => Err(unexpected(other)),
26        }
27    }
28
29    /// `ZREM key member [member ...]`. Returns count actually removed.
30    pub async fn zrem(&mut self, key: &[u8], members: &[&[u8]]) -> io::Result<usize> {
31        set_multi(self.codec_mut(), b"ZREM", key, members).await
32    }
33
34    /// `ZSCORE key member`. `None` if absent.
35    pub async fn zscore(&mut self, key: &[u8], member: &[u8]) -> io::Result<Option<f64>> {
36        match self
37            .codec_mut()
38            .request(&vec3(b"ZSCORE", key, member))
39            .await?
40        {
41            Reply::Bulk(v) => {
42                let s = std::str::from_utf8(&v)
43                    .map_err(|_| io::Error::other("non-utf8 score reply"))?;
44                let n: f64 = s
45                    .parse()
46                    .map_err(|_| io::Error::other(format!("bad score float: {s}")))?;
47                Ok(Some(n))
48            }
49            Reply::Nil => Ok(None),
50            Reply::Error(e) => Err(io::Error::other(string(e))),
51            other => Err(unexpected(other)),
52        }
53    }
54
55    /// `ZCARD key`. 0 if absent.
56    pub async fn zcard(&mut self, key: &[u8]) -> io::Result<usize> {
57        match self.codec_mut().request(&vec2(b"ZCARD", key)).await? {
58            Reply::Int(n) if n >= 0 => Ok(n as usize),
59            Reply::Error(e) => Err(io::Error::other(string(e))),
60            other => Err(unexpected(other)),
61        }
62    }
63
64    /// `ZRANGE key start stop`. Ascending-score order; negative indices
65    /// count from the tail.
66    pub async fn zrange(
67        &mut self,
68        key: &[u8],
69        start: i64,
70        stop: i64,
71    ) -> io::Result<Vec<Vec<u8>>> {
72        let args = vec![
73            b"ZRANGE".to_vec(),
74            key.to_vec(),
75            start.to_string().into_bytes(),
76            stop.to_string().into_bytes(),
77        ];
78        match self.codec_mut().request(&args).await? {
79            Reply::Array(items) => array_to_bulks(items),
80            Reply::Error(e) => Err(io::Error::other(string(e))),
81            other => Err(unexpected(other)),
82        }
83    }
84}