1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! # 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
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────────┐
//! │ 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
//!
//! ```rust,ignore
//! 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?;
//! ```
// Re-export commonly used items
pub use ;
pub use ;
// Re-export config types for convenience
pub use ;
// Re-export Layer 1 for convenience (but consumers can also import directly)
pub use redis_cloud;
pub use redis_enterprise;