kit_rs/config/mod.rs
1//! Configuration module for Kit framework
2//!
3//! This module provides Laravel-like configuration management including:
4//! - Automatic `.env` file loading with environment-based precedence
5//! - Type-safe configuration structs
6//! - Simple API for accessing config values
7//!
8//! # Example
9//!
10//! ```rust,no_run
11//! use kit::{Config, ServerConfig};
12//!
13//! fn main() {
14//! // Initialize config (loads .env files)
15//! Config::init(std::path::Path::new("."));
16//!
17//! // Get typed config
18//! let server = Config::get::<ServerConfig>().unwrap();
19//! println!("Server port: {}", server.port);
20//! }
21//! ```
22
23pub mod env;
24pub mod providers;
25pub mod repository;
26
27pub use env::{env, env_optional, env_required, load_dotenv, Environment};
28pub use providers::{AppConfig, AppConfigBuilder, ServerConfig, ServerConfigBuilder};
29
30use std::path::Path;
31
32/// Main Config facade for accessing configuration
33///
34/// The Config struct provides a centralized way to initialize and access
35/// application configuration. It follows the Laravel pattern of type-safe
36/// configuration with environment variable support.
37pub struct Config;
38
39impl Config {
40 /// Initialize the configuration system
41 ///
42 /// This should be called at application startup, before creating the server.
43 /// It loads environment variables from `.env` files and registers default configs.
44 ///
45 /// # Arguments
46 ///
47 /// * `project_root` - Path to the project root where `.env` files are located
48 ///
49 /// # Returns
50 ///
51 /// The detected environment (Local, Development, Production, etc.)
52 ///
53 /// # Example
54 ///
55 /// ```rust,no_run
56 /// use kit::Config;
57 ///
58 /// let env = Config::init(std::path::Path::new("."));
59 /// println!("Running in {} environment", env);
60 /// ```
61 pub fn init(project_root: &Path) -> Environment {
62 let env = env::load_dotenv(project_root);
63
64 // Register default configs
65 repository::register(AppConfig::from_env());
66 repository::register(ServerConfig::from_env());
67
68 env
69 }
70
71 /// Get a typed config struct from the repository
72 ///
73 /// # Example
74 ///
75 /// ```rust,no_run
76 /// use kit::{Config, ServerConfig};
77 ///
78 /// let server_config = Config::get::<ServerConfig>().unwrap();
79 /// println!("Port: {}", server_config.port);
80 /// ```
81 pub fn get<T: std::any::Any + Send + Sync + Clone + 'static>() -> Option<T> {
82 repository::get::<T>()
83 }
84
85 /// Register a custom config struct
86 ///
87 /// Use this to register your own configuration structs that can be
88 /// retrieved later with `Config::get::<T>()`.
89 ///
90 /// # Example
91 ///
92 /// ```rust,no_run
93 /// use kit::Config;
94 ///
95 /// #[derive(Clone)]
96 /// struct DatabaseConfig {
97 /// host: String,
98 /// port: u16,
99 /// }
100 ///
101 /// Config::register(DatabaseConfig {
102 /// host: "localhost".to_string(),
103 /// port: 5432,
104 /// });
105 /// ```
106 pub fn register<T: std::any::Any + Send + Sync + 'static>(config: T) {
107 repository::register(config);
108 }
109
110 /// Check if a config type is registered
111 pub fn has<T: std::any::Any + 'static>() -> bool {
112 repository::has::<T>()
113 }
114
115 /// Get the current environment
116 ///
117 /// Returns the environment from AppConfig if initialized,
118 /// otherwise detects from the APP_ENV environment variable.
119 pub fn environment() -> Environment {
120 Config::get::<AppConfig>()
121 .map(|c| c.environment)
122 .unwrap_or_else(Environment::detect)
123 }
124
125 /// Check if running in production environment
126 pub fn is_production() -> bool {
127 Self::environment().is_production()
128 }
129
130 /// Check if running in development environment (local or development)
131 pub fn is_development() -> bool {
132 Self::environment().is_development()
133 }
134
135 /// Check if debug mode is enabled
136 pub fn is_debug() -> bool {
137 Config::get::<AppConfig>()
138 .map(|c| c.debug)
139 .unwrap_or(true)
140 }
141}