redisctl-core 0.12.1

Core library for Redis CLI tools - config, workflows, and shared logic
Documentation
//! # 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
//! - **Client resolution** - Shared profile, credential, endpoint, and TLS handling
//! - **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)                                   │
//! │  - Client resolution (ClientResolver)                           │
//! │  - 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?;
//! ```

/// `User-Agent` sent by every redisctl HTTP client.
///
/// The Redis Cloud API recognises the `redisctl/` prefix as a trusted client for some operations
/// (free-tier provisioning among them), so all consumers — CLI and MCP alike — must send it.
pub const USER_AGENT: &str = concat!("redisctl/", env!("CARGO_PKG_VERSION"));

/// Bound and flatten text from an upstream service before it reaches an error message.
///
/// Those messages are read by agents as well as people, so third-party text must not arrive with
/// newlines or control characters, or at arbitrary length.
pub(crate) fn bound_upstream_text(text: &str) -> String {
    const MAX: usize = 200;
    let flattened: String = text
        .chars()
        .map(|c| if c.is_control() { ' ' } else { c })
        .take(MAX)
        .collect();
    let trimmed = flattened.trim().to_string();
    if text.chars().count() > MAX {
        format!("{trimmed}…")
    } else {
        trimmed
    }
}

pub mod auth;
pub mod clients;
pub mod config;
pub mod error;
pub mod progress;

pub mod cloud;
pub mod enterprise;

// Re-export commonly used items
pub use auth::{
    AuthError, CapiKey, CloudAuthenticator, DeviceAuthorization, DeviceFlowClient,
    LoopbackFlowClient, MintedCredentials, SmAccount, SmApiClient, SmUser, TokenSet,
};
pub use error::{CoreError, Result};
pub use progress::{ProgressCallback, ProgressEvent, poll_task};

// Re-export config types for convenience
pub use clients::{
    ClientResolutionError, ClientResolver, ResolvedCloudConnection, ResolvedEnterpriseConnection,
};
pub use config::{
    CloudAuthConfig, Config, ConfigError, CredentialStorage, CredentialStore, DeploymentType,
    EnvironmentOverrides, Profile, ProfileCredentials,
};

// Re-export Layer 1 for convenience (but consumers can also import directly)
pub use redis_cloud;
pub use redis_enterprise;