iron_config_loader
Unified configuration management for Iron Runtime with precedence-based resolution.
Configuration Precedence
Configuration is resolved using the following precedence (highest to lowest):
- Environment Variables -
{MODULE}_KEY_NAMEformat (highest priority) - Project Config -
{workspace}/config/{module}.{env}.toml - User Config -
~/.config/iron/{module}.toml - Workspace Defaults -
{workspace}/config/{module}.default.toml - Crate Defaults - Hardcoded defaults in crate (lowest priority)
Features
- Precedence-based resolution: Clear, predictable configuration loading
- Environment variable overrides: Override any config value via env vars
- Multiple file layers: Project, user, and workspace-level configuration
- Type-safe deserialization: Automatic conversion to Rust types via serde
- Source tracking: Know which layer provided each configuration value
- Workspace-relative paths: Context-independent configuration files
Quick Start
Basic Example
use ConfigLoader;
use Deserialize;
Environment Variable Overrides
Environment variables follow the pattern {MODULE}_{KEY_PATH}:
# Override database.url for iron_token_manager
# Override database.max_connections
# Override nested values: database.pool.timeout
Configuration files use TOML format:
Project Config ({workspace}/config/iron_token_manager.development.toml):
[]
= "sqlite:///{workspace}/iron.db?mode=rwc"
= 5
= true
[]
= true
= false
User Config (~/.config/iron/iron_token_manager.toml):
[]
= true # Personal preference
Load with specific environment:
let loader = with_env?;
Provide default values:
let defaults = r#"
[database]
url = "sqlite:///:memory:"
max_connections = 5
"#;
let loader = with_defaults?;
Get value with source information:
let = loader.?;
println!;
// Output: Database URL: sqlite:///iron.db (from env:IRON_TOKEN_MANAGER_DATABASE_URL)
Debug configuration:
println!;
Adding to your crate
Cargo.toml:
[]
= { = true }
= { = true, = ["derive"] }
Migration from custom config
Before (custom config loading):
// Old: 252 lines of HashMap-based config hierarchy
let config = load_config_from_multiple_sources?;
After (iron_config_loader):
// New: Single line with full precedence system
let loader = new?;
let config: MyConfig = loader.get_section?;
This crate is part of Phase 2 (Configuration Unification) of the workspace_tools adoption plan:
- ✅ Create unified configuration system
- ✅ Migrate iron_token_manager (verified via 5-tier testing)
- ✅ Migrate iron_cli (verified via 5-tier testing)
- ⏳ Migrate iron_control_api (future work)
- ✅ Eliminate module-specific config loaders (iron_token_manager, iron_cli)
- ⏳ Workspace-wide migration (future phases)
iron_config_loader/
├── src/
│ ├── lib.rs # Public API
│ ├── error.rs # Error types
│ ├── layer.rs # Configuration layer implementations
│ └── loader.rs # ConfigLoader implementation
├── tests/
│ ├── precedence_test.rs # Precedence system tests
│ ├── env_layer_test.rs # Environment variable layer tests
│ └── file_layer_test.rs # File layer tests
├── Cargo.toml
└── readme.md
Dependencies
- workspace_tools - Workspace detection and path resolution
- serde - Serialization/deserialization
- toml - TOML parsing
- thiserror - Error handling
- dirs - User directory detection
Testing
Run tests:
Run tests with clippy:
License
MIT