mecha10-core 0.6.2

Mecha10 core runtime and foundational types
Documentation
//! Shared helper for the "list all items referenced by a Redis set" pattern.
//!
//! Both `AuthExt::list_policies` (in [`crate::auth`]) and `SchemaRegistryExt::list_schemas`
//! (in [`crate::schema::registry_impl`]) connect to Redis, read the members of a set that
//! tracks known item names, then fetch each item individually — skipping any that are
//! missing. [`collect_from_redis_set`] factors that shape out so each call site only
//! supplies the set key and a per-item fetcher.

use crate::context::Context;
use crate::error::{Mecha10Error, Result};
use redis::AsyncCommands;
use std::future::Future;

/// Connects to Redis, reads the members of `list_key`, and fetches each one via
/// `get_item`, collecting the ones that are found.
pub(crate) async fn collect_from_redis_set<T, F, Fut>(list_key: &str, get_item: F) -> Result<Vec<T>>
where
    F: Fn(String) -> Fut,
    Fut: Future<Output = Result<Option<T>>> + Send,
{
    let redis_url = Context::get_redis_url()?;
    let client = redis::Client::open(redis_url.as_str()).map_err(|e| Mecha10Error::MessagingError {
        message: format!("Failed to connect to Redis: {}", e),
        suggestion: "Ensure Redis is running".to_string(),
    })?;

    let mut conn = client
        .get_multiplexed_async_connection()
        .await
        .map_err(|e| Mecha10Error::MessagingError {
            message: format!("Failed to get Redis connection: {}", e),
            suggestion: "Ensure Redis is running".to_string(),
        })?;

    let keys: Vec<String> = conn
        .smembers(list_key)
        .await
        .map_err(|e| Mecha10Error::MessagingError {
            message: format!("Failed to get list: {}", e),
            suggestion: "Check Redis connection".to_string(),
        })?;

    let mut items = Vec::new();
    for key in keys {
        if let Some(item) = get_item(key).await? {
            items.push(item);
        }
    }

    Ok(items)
}