use cfgmatic_source::prelude::*;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct AppConfig {
server: ServerConfig,
database: DatabaseConfig,
}
#[derive(Debug, Deserialize)]
struct ServerConfig {
host: String,
port: u16,
}
#[derive(Debug, Deserialize)]
struct DatabaseConfig {
url: String,
max_connections: u32,
}
fn main() -> Result<()> {
println!("=== cfgmatic-source Basic Example ===\n");
memory_source_example()?;
env_source_example()?;
composite_source_example()?;
println!("\nAll examples completed successfully!");
Ok(())
}
fn memory_source_example() -> Result<()> {
println!("--- Memory Source Example ---");
let json_config = serde_json::json!({
"server": {
"host": "localhost",
"port": 8080
},
"database": {
"url": "postgres://localhost/mydb",
"max_connections": 10
}
});
let source = MemorySource::from_json(json_config);
let loader = Loader::new();
let config: AppConfig = loader.load_as(&source)?;
println!("Loaded from memory: {:?}", config);
println!("Server: {}:{}", config.server.host, config.server.port);
Ok(())
}
fn env_source_example() -> Result<()> {
println!("\n--- Environment Source Example ---");
let source = EnvSource::builder().prefix("MYAPP").required(false).build();
let metadata = source.metadata();
println!(
"Source: {} (priority: {})",
metadata.name, metadata.priority
);
println!("Format: {:?}", source.detect_format());
match source.load_raw() {
Ok(content) if !content.is_empty() => {
println!("Loaded from environment: {} bytes", content.len());
}
_ => {
println!("No environment variables with MYAPP_ prefix found.");
println!("Set MYAPP_SERVER_HOST, MYAPP_SERVER_PORT, etc. to test.");
}
}
Ok(())
}
fn composite_source_example() -> Result<()> {
println!("\n--- Composite Source Example ---");
let base_config = serde_json::json!({
"server": {
"host": "0.0.0.0",
"port": 3000
},
"database": {
"url": "postgres://localhost/default",
"max_connections": 5
}
});
let override_config = serde_json::json!({
"server": {
"port": 8080
},
"database": {
"max_connections": 20
}
});
let base = MemorySource::from_json(base_config);
let override_src = MemorySource::from_json(override_config);
let composite = CompositeSource::builder()
.add_with_priority(base, SourcePriority::new(1)) .add_with_priority(override_src, SourcePriority::new(10)) .build();
let loader = Loader::new();
let config: AppConfig = loader.load_as(&composite)?;
println!("Merged configuration:");
println!(" Server: {}:{}", config.server.host, config.server.port);
println!(
" Database: {} (max: {})",
config.database.url, config.database.max_connections
);
println!(" Note: port and max_connections came from override");
Ok(())
}