cal-redis 0.1.80

Callable Redis Implementation
Documentation
// File: cal-redis/src/common.rs

use redis::{AsyncCommands, ErrorKind, RedisError, RedisResult, Value};
use redis::aio::MultiplexedConnection;
use serde::de::DeserializeOwned;
use serde::Serialize;

/// Serializes an item to a JSON string with proper error handling.
pub fn serialize_to_json<T: Serialize>(item: &T) -> Result<String, RedisError> {
    serde_json::to_string(item).map_err(|e| RedisError::from((
        ErrorKind::ClientError,
        "JSON serialization error",
        e.to_string()
    )))
}

/// Deserializes a JSON string into the specified type with proper error handling.
pub fn deserialize_from_json<T: DeserializeOwned>(json: &str) -> Result<T, RedisError> {
    serde_json::from_str(json).map_err(|e| RedisError::from((
        ErrorKind::ClientError,
        "JSON deserialization error",
        e.to_string()
    )))
}

/// Retrieves all values from a Redis hash and deserializes them into the specified type.
pub async fn get_items<T: DeserializeOwned>(
    con: MultiplexedConnection,
    key: &str
) -> Result<Vec<T>, RedisError> {
    let strings: Vec<String> = con.clone().hvals(key).await?;

    let mut items = Vec::with_capacity(strings.len());
    for json_str in strings {
        items.push(deserialize_from_json(&json_str)?);
    }

    Ok(items)
}

/// Retrieves a single value from a Redis hash and deserializes it into the specified type.
pub async fn get_hash_item<T: DeserializeOwned>(
    con: MultiplexedConnection,
    key: &str,
    field: &str
) -> Result<Option<T>, RedisError> {
    match con.clone().hget::<_, _, Option<String>>(key, field).await? {
        Some(json_str) => Ok(Some(deserialize_from_json(&json_str)?)),
        None => Ok(None),
    }
}

/// Retrieves a single value from a Redis key and deserializes it into the specified type.
pub async fn get_item<T: DeserializeOwned>(
    con: MultiplexedConnection,
    key: &str,
) -> Result<Option<T>, RedisError> {
    match con.clone().get::<_, Option<String>>(key).await? {
        Some(json_str) => Ok(Some(deserialize_from_json(&json_str)?)),
        None => Ok(None),
    }
}

/// Inserts multiple items into a Redis hash, serializing each item to JSON.
pub async fn insert_items<T, F>(
    mut con: MultiplexedConnection,
    key: &str,
    items: &[T],
    id_extractor: F,
) -> RedisResult<Value>
where
    T: Serialize,
    F: Fn(&T) -> String,
{
    let mut entries = Vec::with_capacity(items.len());

    for item in items {
        let field = id_extractor(item);
        let value = serialize_to_json(item)?;
        entries.push((field, value));
    }

    con.hset_multiple(key, &entries).await
}