use std::fmt::Debug; use redis::{FromRedisValue, ToRedisArgs}; /// A wrapper on an arbitrary json object to allow reading and writing to redis. /// Access the inner with .0. #[derive(Clone, PartialEq, Eq)] pub struct RedisJson(pub T); impl Debug for RedisJson { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("RedisJson").field(&self.0).finish() } } impl serde::Deserialize<'a>> FromRedisValue for RedisJson { fn from_redis_value(v: &redis::Value) -> redis::RedisResult { match v { redis::Value::BulkString(data) => Ok(Self(serde_json::from_slice(data)?)), _ => Err(redis::RedisError::from(( redis::ErrorKind::TypeError, "Cannot convert to Serialize", ))), } } } impl serde::Deserialize<'a>> ToRedisArgs for RedisJson { fn write_redis_args(&self, out: &mut W) where W: ?Sized + redis::RedisWrite, { let data = serde_json::to_vec(&self.0).unwrap(); out.write_arg(&data) } } /// A borrowed wrapper on an arbitrary json object to writing to redis. /// Use this over [`RedisJson`] when you don't want to own the data and prevent unnecessary cloning. /// Access the inner with .0. pub struct RedisJsonBorrowed<'a, T>(pub &'a T); impl<'a, T: Debug> Debug for RedisJsonBorrowed<'a, T> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("RedisJsonBorrowed").field(&self.0).finish() } } impl<'a, T> ToRedisArgs for RedisJsonBorrowed<'a, T> where // Needs to be serializable from the reference, deserializable to T itself: T: serde::Deserialize<'a>, &'a T: serde::Serialize, { fn write_redis_args(&self, out: &mut W) where W: ?Sized + redis::RedisWrite, { let data = serde_json::to_vec(&self.0).unwrap(); out.write_arg(&data) } }