cal-redis 0.1.80

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

use crate::cache::{get_hash, publish_event};
use crate::common::{
    get_hash_item, get_items, serialize_to_json,
};
use crate::constants::{USERS_KEY, USER_IDENTS_KEY};
use cal_core::{RedisEvent, User, UserCreate};
use redis::aio::MultiplexedConnection;
use redis::{AsyncCommands, RedisError, Value};

/// Retrieves all users stored in Redis.
pub async fn get_users(con: MultiplexedConnection) -> Result<Vec<User>, RedisError> {
    get_items(con, USERS_KEY).await
}

/// Retrieves a user by its identifier (e.g., email).
pub async fn get_user_by_ident(
    con: MultiplexedConnection,
    key: &str,
) -> Result<Option<User>, RedisError> {
    match get_hash(con.clone(), USER_IDENTS_KEY, key).await? {
        Some(user_id) => {
            println!("get_user_by_ident: Found user ident {:?}", user_id);
            get_user_by_id(con, &user_id).await
        }
        None => {
            println!("get_user_by_ident: No user ident for {:?}", key);
            Ok(None)
        }
    }
}

/// Retrieves a user by its unique ID.
pub async fn get_user_by_id(
    con: MultiplexedConnection,
    key: &str,
) -> Result<Option<User>, RedisError> {
    get_hash_item(con, USERS_KEY, key).await
}

/// Inserts a complete user with identity mappings into Redis.
pub async fn insert_user(
    mut con: MultiplexedConnection,
    user: User,
) -> Result<(), RedisError> {
    // Store full user info
    let value = serialize_to_json(&user)?;
    let _: Value = con.hset(USERS_KEY, &user.id, value).await?;

    // Build user identity mappings
    build_user_idents(&mut con, &user).await?;

    let event = RedisEvent::UserCreate(UserCreate {
        payload: user.clone(),
    });

    publish_event(&mut con, event).await?;

    Ok(())
}

/// Builds Redis identity mappings for a user
async fn build_user_idents(
    con: &mut MultiplexedConnection,
    user: &User,
) -> Result<(), RedisError> {
    // Add user ID and email mappings
    let ident_entries = vec![
        (user.id.clone(), user.id.clone()),
        (user.email.clone(), user.id.clone()),
    ];

    // Insert all identity entries
    let _: Value = con.hset_multiple(USER_IDENTS_KEY, &ident_entries).await?;

    Ok(())
}