config.rs (2698B)
1 //! Configuration management for the inventory service 2 //! 3 //! This module handles loading and parsing configuration from multiple sources: 4 //! 1. config.toml file (base configuration) 5 //! 2. Environment variables prefixed with `INVENTORY_` (overrides) 6 //! 7 //! # Environment Variables 8 //! - `INVENTORY_SERVER_PORT` - Override server port 9 //! - `INVENTORY_DATABASE_URL` - Override database connection string 10 //! - `INVENTORY_DATABASE_MAX_CONNECTIONS` - Override max database connections 11 //! 12 //! # Example config.toml 13 //! ```toml 14 //! [server] 15 //! port = 3002 16 //! 17 //! [database] 18 //! url = "postgres://user:pass@localhost:5432/dbname" 19 //! max_connections = 10 20 //! ``` 21 22 use anyhow::Result; 23 use serde::Deserialize; 24 25 /// Root configuration structure 26 /// 27 /// Loaded from config.toml and can be overridden with environment variables. 28 #[derive(Debug, Deserialize, Clone)] 29 pub struct Config { 30 /// Server configuration (port) 31 pub server: ServerConfig, 32 33 /// Database connection configuration 34 pub database: DatabaseConfig, 35 } 36 37 /// Server configuration 38 #[derive(Debug, Deserialize, Clone)] 39 pub struct ServerConfig { 40 /// Port to bind the HTTP server to (default: 3002) 41 pub port: u16, 42 } 43 44 /// Database connection configuration 45 #[derive(Debug, Deserialize, Clone)] 46 pub struct DatabaseConfig { 47 /// PostgreSQL connection string 48 /// Format: postgres://user:password@host:port/database 49 pub url: String, 50 51 /// Maximum number of connections in the connection pool 52 /// Recommended: 5-20 for most applications 53 pub max_connections: u32, 54 } 55 56 impl Config { 57 /// Load configuration from config.toml and environment variables 58 /// 59 /// Configuration is loaded in this order (later sources override earlier ones): 60 /// 1. config.toml in the current directory 61 /// 2. Environment variables with `INVENTORY_` prefix 62 /// 63 /// # Example Environment Override 64 /// ```bash 65 /// export INVENTORY_SERVER_PORT=8080 66 /// export INVENTORY_DATABASE_URL=postgres://localhost/mydb 67 /// ``` 68 /// 69 /// # Errors 70 /// Returns an error if: 71 /// - config.toml is not found or invalid 72 /// - Required fields are missing 73 /// - Environment variable format is invalid 74 pub fn load() -> Result<Self> { 75 let config = config::Config::builder() 76 // Load from config.toml file 77 .add_source(config::File::with_name("config")) 78 // Override with environment variables (e.g., INVENTORY_SERVER_PORT) 79 .add_source(config::Environment::with_prefix("INVENTORY")) 80 .build()?; 81 82 // Deserialize into our Config struct 83 let config: Config = config.try_deserialize()?; 84 Ok(config) 85 } 86 }