use std::collections::HashMap; use redis::{AsyncCommands, Cmd, FromRedisValue, ToRedisArgs, ToSingleRedisArg}; use serde::Serialize; use serde::de::DeserializeOwned; use crate::error::{CacheError, CacheResult}; use crate::json::{decode, encode}; use crate::kv::Cache; impl Cache { pub async fn hget( &self, key: &str, field: &str, ) -> CacheResult> { let mut conn = self.conn().clone(); conn.hget(key, field).await.map_err(CacheError::from) } pub async fn hget_bytes(&self, key: &str, field: &str) -> CacheResult>> { self.hget::>(key, field).await } pub async fn hget_json( &self, key: &str, field: &str, ) -> CacheResult> { match self.hget_bytes(key, field).await? { Some(bytes) => Ok(Some(decode(key, &bytes)?)), None => Ok(None), } } pub async fn hmget( &self, key: &str, fields: F, ) -> CacheResult>> { let mut conn = self.conn().clone(); conn.hmget(key, fields).await.map_err(CacheError::from) } pub async fn hset( &self, key: &str, field: F, value: V, ) -> CacheResult { let mut conn = self.conn().clone(); conn.hset(key, field, value).await.map_err(CacheError::from) } pub async fn hset_json( &self, key: &str, field: F, value: &V, ) -> CacheResult { self.hset(key, field, encode(key, value)?).await } pub async fn hset_nx( &self, key: &str, field: &str, value: V, ) -> CacheResult { let mut cmd = Cmd::new(); cmd.arg("HSETNX").arg(key).arg(field).arg(value); self.exec(&cmd).await } pub async fn hset_multiple< F: ToSingleRedisArg + Send + Sync, V: ToSingleRedisArg + Send + Sync, >( &self, key: &str, items: &[(F, V)], ) -> CacheResult<()> { let mut conn = self.conn().clone(); conn.hset_multiple(key, items) .await .map_err(CacheError::from) } pub async fn hset_multiple_json( &self, key: &str, items: &[(F, V)], ) -> CacheResult<()> { let mut encoded = Vec::with_capacity(items.len()); for (field, value) in items { encoded.push((field, encode(key, value)?)); } let mut conn = self.conn().clone(); conn.hset_multiple(key, &encoded) .await .map_err(CacheError::from) } pub async fn hgetall( &self, key: &str, ) -> CacheResult> { let mut conn = self.conn().clone(); conn.hgetall(key).await.map_err(CacheError::from) } pub async fn hgetall_bytes(&self, key: &str) -> CacheResult>> { self.hgetall::>(key).await } pub async fn hgetall_json( &self, key: &str, ) -> CacheResult> { let raw = self.hgetall_bytes(key).await?; let mut decoded = HashMap::with_capacity(raw.len()); for (field, bytes) in raw { let value = decode(&field, &bytes)?; decoded.insert(field, value); } Ok(decoded) } pub async fn hdel( &self, key: &str, fields: F, ) -> CacheResult { let mut conn = self.conn().clone(); conn.hdel(key, fields).await.map_err(CacheError::from) } pub async fn hexists(&self, key: &str, field: &str) -> CacheResult { let mut conn = self.conn().clone(); conn.hexists(key, field).await.map_err(CacheError::from) } pub async fn hlen(&self, key: &str) -> CacheResult { let mut conn = self.conn().clone(); conn.hlen(key).await.map_err(CacheError::from) } pub async fn hkeys(&self, key: &str) -> CacheResult> { let mut conn = self.conn().clone(); conn.hkeys(key).await.map_err(CacheError::from) } pub async fn hvals(&self, key: &str) -> CacheResult> { let mut conn = self.conn().clone(); conn.hvals(key).await.map_err(CacheError::from) } pub async fn hincr(&self, key: &str, field: &str, delta: i64) -> CacheResult { let mut conn = self.conn().clone(); conn.hincr(key, field, delta) .await .map_err(CacheError::from) } }