use crate::error::Result;
use crate::executor::CommandExecutor;
use crate::value;
use async_trait::async_trait;
use bytes::Bytes;
use redis::{Cmd, ToRedisArgs};
#[async_trait]
pub trait JsonCommands: CommandExecutor {
async fn json_set<K: ToRedisArgs + Send, P: ToRedisArgs + Send, V: ToRedisArgs + Send>(
&self,
key: K,
path: P,
value: V,
) -> Result<()> {
let mut cmd = Cmd::new();
cmd.arg("JSON.SET").arg(key).arg(path).arg(value);
crate::value::to_unit(self.execute_command(cmd, None).await?)
}
async fn json_get<K: ToRedisArgs + Send, P: ToRedisArgs + Send + Sync>(
&self,
key: K,
paths: &[P],
) -> Result<Option<Bytes>> {
let mut cmd = Cmd::new();
cmd.arg("JSON.GET").arg(key);
for p in paths {
cmd.arg(p);
}
value::to_opt_bytes(self.execute_command(cmd, None).await?)
}
async fn json_del<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<i64> {
let mut cmd = Cmd::new();
cmd.arg("JSON.DEL").arg(key).arg(path);
value::to_i64(self.execute_command(cmd, None).await?)
}
async fn json_forget<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<i64> {
let mut cmd = Cmd::new();
cmd.arg("JSON.FORGET").arg(key).arg(path);
value::to_i64(self.execute_command(cmd, None).await?)
}
async fn json_type<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.TYPE").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_numincrby<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
value: f64,
) -> Result<Option<Bytes>> {
let mut cmd = Cmd::new();
cmd.arg("JSON.NUMINCRBY").arg(key).arg(path).arg(value);
crate::value::to_opt_bytes(self.execute_command(cmd, None).await?)
}
async fn json_nummultby<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
value: f64,
) -> Result<Option<Bytes>> {
let mut cmd = Cmd::new();
cmd.arg("JSON.NUMMULTBY").arg(key).arg(path).arg(value);
crate::value::to_opt_bytes(self.execute_command(cmd, None).await?)
}
async fn json_strappend<K: ToRedisArgs + Send, P: ToRedisArgs + Send, V: ToRedisArgs + Send>(
&self,
key: K,
path: P,
value: V,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.STRAPPEND").arg(key).arg(path).arg(value);
self.execute_command(cmd, None).await
}
async fn json_strlen<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.STRLEN").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_arrappend<
K: ToRedisArgs + Send,
P: ToRedisArgs + Send,
V: ToRedisArgs + Send + Sync,
>(
&self,
key: K,
path: P,
values: &[V],
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.ARRAPPEND").arg(key).arg(path);
for v in values {
cmd.arg(v);
}
self.execute_command(cmd, None).await
}
async fn json_arrinsert<
K: ToRedisArgs + Send,
P: ToRedisArgs + Send,
V: ToRedisArgs + Send + Sync,
>(
&self,
key: K,
path: P,
index: i64,
values: &[V],
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.ARRINSERT").arg(key).arg(path).arg(index);
for v in values {
cmd.arg(v);
}
self.execute_command(cmd, None).await
}
async fn json_arrlen<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.ARRLEN").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_arrpop<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
index: Option<i64>,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.ARRPOP").arg(key).arg(path);
if let Some(i) = index {
cmd.arg(i);
}
self.execute_command(cmd, None).await
}
async fn json_arrtrim<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
start: i64,
stop: i64,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.ARRTRIM")
.arg(key)
.arg(path)
.arg(start)
.arg(stop);
self.execute_command(cmd, None).await
}
async fn json_objkeys<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.OBJKEYS").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_objlen<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.OBJLEN").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_toggle<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.TOGGLE").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_clear<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<i64> {
let mut cmd = Cmd::new();
cmd.arg("JSON.CLEAR").arg(key).arg(path);
value::to_i64(self.execute_command(cmd, None).await?)
}
async fn json_arrindex<K: ToRedisArgs + Send, P: ToRedisArgs + Send, V: ToRedisArgs + Send>(
&self,
key: K,
path: P,
value: V,
range: Option<(i64, i64)>,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.ARRINDEX").arg(key).arg(path).arg(value);
if let Some((start, end)) = range {
cmd.arg(start).arg(end);
}
self.execute_command(cmd, None).await
}
async fn json_mget<K: ToRedisArgs + Send + Sync, P: ToRedisArgs + Send>(
&self,
keys: &[K],
path: P,
) -> Result<Vec<Option<Bytes>>> {
let mut cmd = Cmd::new();
cmd.arg("JSON.MGET");
for k in keys {
cmd.arg(k);
}
cmd.arg(path);
match self.execute_command(cmd, None).await? {
redis::Value::Array(items) => items.into_iter().map(value::to_opt_bytes).collect(),
redis::Value::Nil => Ok(Vec::new()),
other => Ok(vec![value::to_opt_bytes(other)?]),
}
}
async fn json_resp<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.RESP").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_debug_memory<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.DEBUG").arg("MEMORY").arg(key).arg(path);
self.execute_command(cmd, None).await
}
async fn json_debug_fields<K: ToRedisArgs + Send, P: ToRedisArgs + Send>(
&self,
key: K,
path: P,
) -> Result<redis::Value> {
let mut cmd = Cmd::new();
cmd.arg("JSON.DEBUG").arg("FIELDS").arg(key).arg(path);
self.execute_command(cmd, None).await
}
}
impl<T: CommandExecutor + ?Sized> JsonCommands for T {}