use service_builder::builder;
use std::time::Duration;
#[builder]
struct DatabaseConfig {
connection_string: String,
#[builder(default = "Duration::from_secs(30)")]
timeout: Duration,
#[builder(default)]
ssl_enabled: bool,
#[builder(optional)]
max_connections: Option<usize>,
#[builder(default = "5")]
retry_count: u32,
}
fn main() {
println!("=== Config with Defaults Example ===\n");
println!("1. Minimal configuration with defaults:");
let config = DatabaseConfig::builder()
.connection_string("postgres://localhost/mydb".to_string())
.build_with_defaults()
.unwrap();
println!(" Connection: {}", config.connection_string);
println!(" Timeout: {:?}", config.timeout);
println!(" SSL Enabled: {}", config.ssl_enabled);
println!(" Max Connections: {:?}", config.max_connections);
println!(" Retry Count: {}\n", config.retry_count);
println!("2. Override some defaults:");
let config = DatabaseConfig::builder()
.connection_string("postgres://prod/db".to_string())
.timeout(Duration::from_secs(60))
.ssl_enabled(true)
.max_connections(Some(100))
.build_with_defaults()
.unwrap();
println!(" Connection: {}", config.connection_string);
println!(" Timeout: {:?}", config.timeout);
println!(" SSL Enabled: {}", config.ssl_enabled);
println!(" Max Connections: {:?}", config.max_connections);
println!(" Retry Count: {}\n", config.retry_count);
println!("3. Using strict build() method:");
let config = DatabaseConfig::builder()
.connection_string("postgres://test/db".to_string())
.build()
.unwrap();
println!(" Connection: {}", config.connection_string);
println!(" Timeout: {:?}", config.timeout);
println!(" SSL Enabled: {}", config.ssl_enabled);
println!(" Max Connections: {:?}", config.max_connections);
println!(" Retry Count: {}\n", config.retry_count);
println!("4. Error handling - missing required field:");
let result = DatabaseConfig::builder()
.timeout(Duration::from_secs(10))
.build();
match result {
Err(e) => println!(" Error: {}", e),
Ok(_) => println!(" Unexpected success!"),
}
}
#[builder]
struct AppConfig {
#[builder(default = "\"My App\".to_string()")]
app_name: String,
#[builder(default = "8080")]
port: u16,
#[builder(default)]
debug_mode: bool,
#[builder(optional)]
custom_header: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_all_defaults_config() {
let config = AppConfig::builder()
.build()
.unwrap();
assert_eq!(config.app_name, "My App");
assert_eq!(config.port, 8080);
assert_eq!(config.debug_mode, false);
assert_eq!(config.custom_header, None);
}
}