use crate::ValkeyResult;
use crate::cmd::Cmd;
use crate::executor::CommandExecutor;
use crate::value::FromValkeyValue;
use crate::value::ValkeyValue;
use crate::write::ToValkeyArgs;
use async_trait::async_trait;
use bytes::Bytes;
use std::collections::HashSet;
fn collect_bytes(v: ValkeyValue) -> ValkeyResult<Vec<Bytes>> {
match v {
ValkeyValue::Array(items) => items
.into_iter()
.map(Bytes::from_owned_valkey_value)
.collect(),
ValkeyValue::Set(items) => items
.into_iter()
.map(Bytes::from_owned_valkey_value)
.collect(),
ValkeyValue::Nil => Ok(Vec::new()),
other => Ok(vec![Bytes::from_owned_valkey_value(other)?]),
}
}
#[async_trait]
pub trait SetCommands: CommandExecutor {
async fn sintercard<K: ToValkeyArgs + Send + Sync>(&self, keys: &[K]) -> ValkeyResult<i64> {
let mut cmd = Cmd::new();
cmd.arg("SINTERCARD").arg(keys.len());
for k in keys {
cmd.arg(k);
}
i64::from_owned_valkey_value(self.execute_command(cmd, None).await?)
}
async fn sintercard_limit<K: ToValkeyArgs + Send + Sync>(
&self,
keys: &[K],
limit: i64,
) -> ValkeyResult<i64> {
let mut cmd = Cmd::new();
cmd.arg("SINTERCARD").arg(keys.len());
for k in keys {
cmd.arg(k);
}
cmd.arg("LIMIT").arg(limit);
i64::from_owned_valkey_value(self.execute_command(cmd, None).await?)
}
#[doc(hidden)]
async fn set_op<K: ToValkeyArgs + Send + Sync>(
&self,
op: &'static str,
keys: &[K],
) -> ValkeyResult<HashSet<Bytes>> {
let mut cmd = Cmd::new();
cmd.arg(op);
for k in keys {
cmd.arg(k);
}
Ok(collect_bytes(self.execute_command(cmd, None).await?)?
.into_iter()
.collect())
}
#[doc(hidden)]
async fn set_op_store<D: ToValkeyArgs + Send, K: ToValkeyArgs + Send + Sync>(
&self,
op: &'static str,
destination: D,
keys: &[K],
) -> ValkeyResult<i64> {
let mut cmd = Cmd::new();
cmd.arg(op).arg(destination);
for k in keys {
cmd.arg(k);
}
i64::from_owned_valkey_value(self.execute_command(cmd, None).await?)
}
}
impl<T: CommandExecutor + ?Sized> SetCommands for T {}