8 releases (4 breaking)
Uses new Rust 2024
| 0.10.1 | Mar 19, 2026 |
|---|---|
| 0.10.0 | Mar 17, 2026 |
| 0.9.1 | Mar 7, 2026 |
| 0.8.3 | Mar 6, 2026 |
| 0.1.0 | Feb 25, 2026 |
#30 in #cli-config
27 downloads per month
Used in 2 crates
115KB
2K
SLoC
redisctl-core
Layer 2: Higher-level interface on top of redis-cloud and redis-enterprise clients.
This crate provides:
- Unified error handling - CoreError wrapping both platform errors
- Progress callbacks - For Cloud's async task polling
- Module resolution - Validate Enterprise modules before creation
- Workflows - Multi-step operations (create + wait, etc.)
Philosophy
Don't rebuild Layer 1. Use it and add value.
- Simple operations: Use Layer 1 directly (
redis_cloud::DatabaseHandler, etc.) - Operations with progress: Use Layer 2 workflows
- Operations with validation: Use Layer 2 helpers
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Layer 3: Consumers │
│ CLI (redisctl) MCP (redisctl-mcp) │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Layer 2: redisctl-core │
│ - Unified errors (CoreError) │
│ - Progress callbacks (poll_task) │
│ - Module resolution (resolve_modules) │
│ - Workflows (create_and_wait, etc.) │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Layer 1: Raw API Clients │
│ redis-cloud redis-enterprise │
└─────────────────────────────────────────────────────────────────┘
Example Usage
use redis_cloud::{CloudClient, DatabaseHandler};
use redisctl_core::{poll_task, ProgressEvent};
use std::time::Duration;
// Simple operation: use Layer 1 directly
let handler = DatabaseHandler::new(client.clone());
let databases = handler.list(subscription_id).await?;
// Operation with progress: use Layer 2
let task = handler.create(subscription_id, &request).await?;
let completed = poll_task(
&client,
&task.task_id.unwrap(),
Duration::from_secs(600),
Duration::from_secs(10),
Some(Box::new(|event| {
if let ProgressEvent::Polling { status, elapsed, .. } = event {
println!("Status: {} ({:.0}s)", status, elapsed.as_secs());
}
})),
).await?;
Dependencies
~14–35MB
~394K SLoC