Rustelo/server/examples/config_example.rs

308 lines
9.6 KiB
Rust
Raw Normal View History

2025-07-07 23:05:19 +01:00
//! Configuration System Example
//!
//! This example demonstrates how to use the configuration system
//! with TOML files and environment variable overrides.
use server::config::{Config, Environment, Protocol};
use tempfile::tempdir;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Configuration System Example ===\n");
// Example 1: Load default configuration
println!("1. Loading default configuration...");
match Config::load() {
Ok(config) => {
println!("✓ Configuration loaded successfully");
println!(" Server: {}:{}", config.server.host, config.server.port);
println!(" Environment: {:?}", config.server.environment);
println!(" Database: {}", config.database.url);
println!(" App Name: {}", config.app.name);
println!(" Debug Mode: {}", config.app.debug);
// Show server directories
println!(" Server Directories:");
println!(" Public: {}", config.server_dirs.public_dir);
println!(" Uploads: {}", config.server_dirs.uploads_dir);
println!(" Logs: {}", config.server_dirs.logs_dir);
println!(" Cache: {}", config.server_dirs.cache_dir);
}
Err(e) => {
println!("✗ Failed to load configuration: {}", e);
println!(" This is expected if no config file exists");
}
}
println!("\n{}\n", "=".repeat(50));
// Example 2: Demonstrate TOML file loading
println!("2. Testing TOML file loading...");
let temp_dir = tempdir()?;
let config_path = temp_dir.path().join("test_config.toml");
let test_config = r#"
[server]
protocol = "http"
host = "localhost"
port = 4000
environment = "development"
log_level = "debug"
[database]
url = "postgresql://test:test@localhost:5432/test_db"
max_connections = 5
min_connections = 1
connect_timeout = 30
idle_timeout = 600
max_lifetime = 1800
[session]
secret = "test-secret-key"
cookie_name = "test_session"
cookie_secure = false
cookie_http_only = true
cookie_same_site = "lax"
max_age = 7200
[cors]
allowed_origins = ["http://localhost:4000"]
allowed_methods = ["GET", "POST"]
allowed_headers = ["Content-Type"]
allow_credentials = true
max_age = 3600
[static]
assets_dir = "public"
site_root = "target/site"
site_pkg_dir = "pkg"
[server_dirs]
public_dir = "public"
uploads_dir = "uploads"
logs_dir = "logs"
temp_dir = "tmp"
cache_dir = "cache"
config_dir = "config"
data_dir = "data"
backup_dir = "backups"
[security]
enable_csrf = false
csrf_token_name = "csrf_token"
rate_limit_requests = 1000
rate_limit_window = 60
bcrypt_cost = 4
[oauth]
enabled = false
[email]
enabled = false
smtp_host = "localhost"
smtp_port = 587
smtp_username = ""
smtp_password = ""
from_email = "test@example.com"
from_name = "Test App"
[redis]
enabled = false
url = "redis://localhost:6379"
pool_size = 10
connection_timeout = 5
command_timeout = 5
[app]
name = "Test Application"
version = "0.1.0"
debug = true
enable_metrics = true
enable_health_check = true
enable_compression = false
max_request_size = 10485760
[logging]
format = "text"
level = "debug"
file_path = "logs/test.log"
max_file_size = 10485760
max_files = 5
enable_console = true
enable_file = true
[content]
enabled = false
content_dir = "content"
cache_enabled = false
cache_ttl = 60
max_file_size = 5242880
[features]
auth = true
tls = false
content_db = true
two_factor_auth = false
"#;
std::fs::write(&config_path, test_config)?;
match Config::load_from_file(&config_path) {
Ok(config) => {
println!("✓ Configuration loaded from TOML file");
println!(" Server: {}:{}", config.server.host, config.server.port);
println!(" App Name: {}", config.app.name);
println!(" Database: {}", config.database.url);
}
Err(e) => {
println!("✗ Failed to load from TOML file: {}", e);
}
}
println!("\n{}\n", "=".repeat(50));
// Example 3: Demonstrate configuration validation
println!("3. Testing configuration validation...");
// Create a config that should pass validation
let valid_config = Config::default();
match valid_config.validate() {
Ok(_) => {
println!("✓ Default configuration validation passed");
}
Err(e) => {
println!("✗ Default configuration validation failed: {}", e);
}
}
println!("\n{}\n", "=".repeat(50));
// Example 4: Demonstrate configuration helper methods
println!("4. Testing configuration helper methods...");
let config = Config::default();
println!("✓ Configuration methods:");
println!(" Server Address: {}", config.server_address());
println!(" Server URL: {}", config.server_url());
println!(" Is Development: {}", config.is_development());
println!(" Is Production: {}", config.is_production());
println!(" Requires TLS: {}", config.requires_tls());
// Database pool configuration
let pool_config = config.database_pool_config();
println!(" Database Pool Config:");
println!(" Max Connections: {}", pool_config.max_connections);
println!(" Min Connections: {}", pool_config.min_connections);
println!(" Connect Timeout: {:?}", pool_config.connect_timeout);
println!("\n{}\n", "=".repeat(50));
// Example 5: Show feature flags
println!("5. Feature flags configuration...");
let config = Config::default();
println!("✓ Feature flags:");
println!(" Auth: {:?}", config.features.auth);
println!(" RBAC: {:?}", config.features.rbac);
println!(" Content: {:?}", config.features.content);
println!(" Security: {:?}", config.features.security);
println!("\n{}\n", "=".repeat(50));
// Example 6: Show server directories configuration
println!("6. Server directories configuration...");
let config = Config::default();
println!("✓ Server directories:");
println!(" Public Directory: {}", config.server_dirs.public_dir);
println!(" Uploads Directory: {}", config.server_dirs.uploads_dir);
println!(" Logs Directory: {}", config.server_dirs.logs_dir);
println!(" Temp Directory: {}", config.server_dirs.temp_dir);
println!(" Cache Directory: {}", config.server_dirs.cache_dir);
println!(" Config Directory: {}", config.server_dirs.config_dir);
println!(" Data Directory: {}", config.server_dirs.data_dir);
println!(" Backup Directory: {}", config.server_dirs.backup_dir);
println!("\n{}\n", "=".repeat(50));
// Example 7: Show security configuration
println!("7. Security configuration...");
let config = Config::default();
println!("✓ Security settings:");
println!(" CSRF Enabled: {}", config.security.enable_csrf);
println!(
" Rate Limit: {} requests/{} seconds",
config.security.rate_limit_requests, config.security.rate_limit_window
);
println!(" BCrypt Cost: {}", config.security.bcrypt_cost);
println!(" Session Config:");
println!(" Cookie Name: {}", config.session.cookie_name);
println!(" Cookie Secure: {}", config.session.cookie_secure);
println!(" Cookie HTTP Only: {}", config.session.cookie_http_only);
println!(" Max Age: {} seconds", config.session.max_age);
println!("\n{}\n", "=".repeat(50));
// Example 8: Create a custom configuration programmatically
println!("8. Creating custom configuration...");
let custom_config = Config {
server: server::config::ServerConfig {
protocol: Protocol::Http,
host: "0.0.0.0".to_string(),
port: 8080,
environment: Environment::Development,
log_level: "debug".to_string(),
tls: None,
},
app: server::config::AppConfig {
name: "Custom Example App".to_string(),
version: "2.0.0".to_string(),
debug: true,
enable_metrics: true,
enable_health_check: true,
enable_compression: false,
max_request_size: 5 * 1024 * 1024, // 5MB
admin_email: Some("admin@example.com".to_string()),
},
server_dirs: server::config::ServerDirConfig {
public_dir: "custom_public".to_string(),
uploads_dir: "custom_uploads".to_string(),
logs_dir: "custom_logs".to_string(),
temp_dir: "custom_tmp".to_string(),
cache_dir: "custom_cache".to_string(),
config_dir: "custom_config".to_string(),
data_dir: "custom_data".to_string(),
backup_dir: "custom_backups".to_string(),
template_dir: Some("custom_templates".to_string()),
},
..Default::default()
};
println!("✓ Custom configuration created:");
println!(" App Name: {}", custom_config.app.name);
println!(" Server: {}", custom_config.server_address());
println!(" Metrics Enabled: {}", custom_config.app.enable_metrics);
println!(
" Custom Public Dir: {}",
custom_config.server_dirs.public_dir
);
println!(
" Custom Uploads Dir: {}",
custom_config.server_dirs.uploads_dir
);
println!("\n{}\n", "=".repeat(50));
println!("Configuration example completed successfully!");
println!("\nTo use this configuration system in your application:");
println!("1. Create a config.toml file in your project root");
println!("2. Use environment-specific files (config.dev.toml, config.prod.toml)");
println!("3. Set environment variables to override specific settings");
println!("4. Call Config::load() in your application");
println!("5. Use config.server_dirs for all directory paths");
Ok(())
}