athena_rs 0.75.4

WIP Database API gateway
Documentation
//! Configuration management for the application.
//!
//! This module provides utilities for loading and accessing application configuration
//! from YAML files. It includes settings for URLs, hosts, API configuration, authentication,
//! PostgreSQL clients, and gateway behavior.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fs;

/// Application configuration loaded from a YAML file.
///
/// Contains all configurable settings including service URLs, hosts, API parameters,
/// authenticator configurations, PostgreSQL client URIs, and gateway settings.
///
/// # Examples
///
/// ```no_run
/// use athena_rs::config::Config;
///
/// let config = Config::load()?;
/// let url = config.get_url("service_name");
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
    pub urls: Vec<HashMap<String, String>>,
    pub hosts: Vec<HashMap<String, String>>,
    pub api: Vec<HashMap<String, String>>,
    pub authenticator: Vec<HashMap<String, HashMap<String, String>>>,
    pub postgres_clients: Vec<HashMap<String, String>>,
    #[serde(default)]
    pub gateway: Vec<HashMap<String, String>>,
}

impl Config {
    /// Load configuration from the default `config.yaml` file.
    pub fn load() -> Result<Self, Box<dyn std::error::Error>> {
        Self::load_from("config.yaml")
    }

    /// Load configuration from a specified file path.
    ///
    /// # Arguments
    ///
    /// * `path` - The file path to load the configuration from.
    pub fn load_from(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let content = fs::read_to_string(path)?;
        let config: Config = serde_yaml::from_str(&content)?;
        Ok(config)
    }

    /// Get the URL for a given service name.
    ///
    /// # Arguments
    ///
    /// * `service` - The name of the service to look up.
    pub fn get_url(&self, service: &str) -> Option<&String> {
        self.urls.iter().find_map(|map| map.get(service))
    }

    /// Get the host for a given service name.
    ///
    /// # Arguments
    ///
    /// * `service` - The name of the service to look up.
    pub fn get_host(&self, service: &str) -> Option<&String> {
        self.hosts.iter().find_map(|map| map.get(service))
    }

    /// Get the API port from configuration.
    pub fn get_api(&self) -> Option<&String> {
        self.api.iter().find_map(|map| map.get("port"))
    }

    /// Get the immortal cache setting from configuration.
    pub fn get_immortal_cache(&self) -> Option<&String> {
        self.api.iter().find_map(|map| map.get("immortal_cache"))
    }

    /// Get the cache TTL (time to live) from configuration.
    pub fn get_cache_ttl(&self) -> Option<&String> {
        self.api.iter().find_map(|map| map.get("cache_ttl"))
    }

    /// Get the connection pool idle timeout from configuration.
    pub fn get_pool_idle_timeout(&self) -> Option<&String> {
        self.api.iter().find_map(|map| map.get("pool_idle_timeout"))
    }

    /// Get the HTTP keep-alive timeout in seconds from configuration.
    pub fn get_http_keep_alive_secs(&self) -> Option<&String> {
        self.api.iter().find_map(|map| map.get("keep_alive_secs"))
    }

    /// Get the client disconnect timeout in seconds from configuration.
    pub fn get_client_disconnect_timeout_secs(&self) -> Option<&String> {
        self.api
            .iter()
            .find_map(|map| map.get("client_disconnect_timeout_secs"))
    }

    /// Get the client request timeout in seconds from configuration.
    pub fn get_client_request_timeout_secs(&self) -> Option<&String> {
        self.api
            .iter()
            .find_map(|map| map.get("client_request_timeout_secs"))
    }

    /// Get the number of HTTP workers from configuration.
    pub fn get_http_workers(&self) -> Option<&String> {
        self.api.iter().find_map(|map| map.get("http_workers"))
    }

    /// Get the maximum number of HTTP connections from configuration.
    pub fn get_http_max_connections(&self) -> Option<&String> {
        self.api
            .iter()
            .find_map(|map| map.get("http_max_connections"))
    }

    /// Get the HTTP backlog from configuration.
    pub fn get_http_backlog(&self) -> Option<&String> {
        self.api.iter().find_map(|map| map.get("http_backlog"))
    }

    /// Get the TCP keepalive timeout in seconds from configuration.
    pub fn get_tcp_keepalive_secs(&self) -> Option<&String> {
        self.api
            .iter()
            .find_map(|map| map.get("tcp_keepalive_secs"))
    }

    /// Get the authenticator configuration for a given service.
    ///
    /// # Arguments
    ///
    /// * `service` - The name of the service to look up.
    pub fn get_authenticator(&self, service: &str) -> Option<&HashMap<String, String>> {
        self.authenticator.iter().find_map(|map| map.get(service))
    }

    /// Get the PostgreSQL URI for a given client name.
    ///
    /// # Arguments
    ///
    /// * `client` - The name of the PostgreSQL client to look up.
    pub fn get_postgres_uri(&self, client: &str) -> Option<&String> {
        self.postgres_clients.iter().find_map(|map| map.get(client))
    }

    /// Get whether to force camelCase to snake_case conversion in the gateway.
    pub fn get_gateway_force_camel_case_to_snake_case(&self) -> bool {
        self.gateway
            .iter()
            .find_map(|map| map.get("force_camel_case_to_snake_case"))
            .and_then(|value| value.parse().ok())
            .unwrap_or(false)
    }
}