mudra-cli 0.1.0

A robust, high-performance currency converter with caching and CLI interface
Documentation
//! Configuration management for the currency converter

use crate::{CurrencyError, Result};
use std::time::Duration;

/// Configuration for the currency converter client
#[derive(Debug, Clone)]
pub struct Config {
    /// Base URL for the API
    pub base_url: String,
    /// API key (optional for some services)
    pub api_key: Option<String>,
    /// Request timeout duration
    pub timeout: Duration,
    /// User agent string for requests
    pub user_agent: String,
    /// Maximum number of retries for failed requests
    pub max_retries: u32,
}

impl Config {
    /// Create a new configuration with default values
    pub fn new() -> Self {
        Config {
            // We'll use exchangerate-api.com for this example (free tier available)
            base_url: "https://v6.exchangerate-api.com/v6".to_string(),
            api_key: None,
            timeout: Duration::from_secs(30),
            user_agent: format!("currency-converter/{}", env!("CARGO_PKG_VERSION")),
            max_retries: 3,
        }
    }

    /// Set the API key from environment variable or explicit value
    pub fn with_api_key<S: Into<String>>(mut self, api_key: S) -> Self {
        self.api_key = Some(api_key.into());
        self
    }

    /// Set the base URL
    pub fn with_base_url<S: Into<String>>(mut self, base_url: S) -> Self {
        self.base_url = base_url.into();
        self
    }

    /// Set the request timeout
    pub fn with_timeout(mut self, timeout: Duration) -> Self {
        self.timeout = timeout;
        self
    }

    /// Load configuration from environment variables
    pub fn from_env() -> Result<Self> {
        let mut config = Config::new();

        // Try to load API key from environment
        if let Ok(api_key) = std::env::var("EXCHANGE_API_KEY") {
            config.api_key = Some(api_key);
        }

        // Try to load base URL from environment (optional)
        if let Ok(base_url) = std::env::var("EXCHANGE_BASE_URL") {
            config.base_url = base_url;
        }

        // Validate that we have an API key (required for most services)
        if config.api_key.is_none() {
            return Err(CurrencyError::configuration(
                "API key not found. Set EXCHANGE_API_KEY environment variable or use with_api_key()",
            ));
        }

        Ok(config)
    }

    /// Get the API key, returning an error if not set
    pub fn get_api_key(&self) -> Result<&str> {
        self.api_key
            .as_deref()
            .ok_or_else(|| CurrencyError::configuration("API key not configured"))
    }
}