1use crate::ValkeyResult;
5use crate::cmd::Cmd;
6use crate::executor::CommandExecutor;
7use crate::value::FromValkeyValue;
8use crate::value::ValkeyValue;
9use crate::write::ToValkeyArgs;
10use async_trait::async_trait;
11use bytes::Bytes;
12use std::collections::HashSet;
13
14fn collect_bytes(v: ValkeyValue) -> ValkeyResult<Vec<Bytes>> {
15 match v {
16 ValkeyValue::Array(items) => items
17 .into_iter()
18 .map(Bytes::from_owned_valkey_value)
19 .collect(),
20 ValkeyValue::Set(items) => items
21 .into_iter()
22 .map(Bytes::from_owned_valkey_value)
23 .collect(),
24 ValkeyValue::Nil => Ok(Vec::new()),
25 other => Ok(vec![Bytes::from_owned_valkey_value(other)?]),
26 }
27}
28
29#[async_trait]
31pub trait SetCommands: CommandExecutor {
32 async fn sintercard<K: ToValkeyArgs + Send + Sync>(&self, keys: &[K]) -> ValkeyResult<i64> {
37 let mut cmd = Cmd::new();
38 cmd.arg("SINTERCARD").arg(keys.len());
39 for k in keys {
40 cmd.arg(k);
41 }
42 i64::from_owned_valkey_value(self.execute_command(cmd, None).await?)
43 }
44
45 async fn sintercard_limit<K: ToValkeyArgs + Send + Sync>(
49 &self,
50 keys: &[K],
51 limit: i64,
52 ) -> ValkeyResult<i64> {
53 let mut cmd = Cmd::new();
54 cmd.arg("SINTERCARD").arg(keys.len());
55 for k in keys {
56 cmd.arg(k);
57 }
58 cmd.arg("LIMIT").arg(limit);
59 i64::from_owned_valkey_value(self.execute_command(cmd, None).await?)
60 }
61
62 #[doc(hidden)]
63 async fn set_op<K: ToValkeyArgs + Send + Sync>(
64 &self,
65 op: &'static str,
66 keys: &[K],
67 ) -> ValkeyResult<HashSet<Bytes>> {
68 let mut cmd = Cmd::new();
69 cmd.arg(op);
70 for k in keys {
71 cmd.arg(k);
72 }
73 Ok(collect_bytes(self.execute_command(cmd, None).await?)?
74 .into_iter()
75 .collect())
76 }
77
78 #[doc(hidden)]
79 async fn set_op_store<D: ToValkeyArgs + Send, K: ToValkeyArgs + Send + Sync>(
80 &self,
81 op: &'static str,
82 destination: D,
83 keys: &[K],
84 ) -> ValkeyResult<i64> {
85 let mut cmd = Cmd::new();
86 cmd.arg(op).arg(destination);
87 for k in keys {
88 cmd.arg(k);
89 }
90 i64::from_owned_valkey_value(self.execute_command(cmd, None).await?)
91 }
92}
93
94impl<T: CommandExecutor + ?Sized> SetCommands for T {}