road-runner-common 0.11.0

Shared Rust utilities for exchange ecosystem backend services.
Documentation
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceConfig {
    pub service_name: String,
    pub log_level: String,  // "info" | "debug" vb
    pub log_format: String, // "json" | "pretty"
    pub max_page_size: u32,
}

impl Default for ServiceConfig {
    fn default() -> Self {
        Self {
            service_name: "my-service".to_string(),
            log_level: "info".to_string(),
            log_format: "json".to_string(),
            max_page_size: 100,
        }
    }
}

impl ServiceConfig {
    pub fn from_env_fallback() -> Self {
        let mut cfg = Self::default();

        if let Ok(v) = std::env::var("SERVICE_NAME") {
            cfg.service_name = v;
        }
        if let Ok(v) = std::env::var("LOG_LEVEL") {
            cfg.log_level = v;
        }
        if let Ok(v) = std::env::var("LOG_FORMAT") {
            cfg.log_format = v;
        }
        if let Ok(v) = std::env::var("MAX_PAGE_SIZE") {
            if let Ok(n) = v.parse::<u32>() {
                cfg.max_page_size = n.max(1);
            }
        }
        cfg
    }

    #[cfg(feature = "config")]
    pub fn load() -> anyhow::Result<Self> {
        let _ = dotenvy::dotenv();

        let config_file = std::env::var("CONFIG_FILE").ok();

        let mut builder = config::Config::builder();

        if let Some(path) = config_file {
            builder = builder.add_source(config::File::with_name(&path).required(false));
        }

        builder = builder.add_source(config::Environment::default());

        let cfg = builder.build()?;
        Ok(cfg.try_deserialize()?)
    }
}