/ examples / advanced.rs
advanced.rs
 1  //! Advanced example with custom `ConfigLoader`, `clap` and a nested config
 2  
 3  use clap::Parser;
 4  use konfik::{ConfigLoader, Error, Konfik, Nested};
 5  
 6  #[derive(serde::Deserialize, Konfik, Debug, Parser)]
 7  struct AppConfig {
 8      database_url: String,
 9  
10      #[arg(short)]
11      port: u16,
12  
13      #[arg(long)]
14      debug: bool,
15  
16      #[command(flatten)]
17      #[serde(default)]
18      logging: Logging,
19  
20      #[serde(skip)]
21      runtime_data: Option<String>,
22  }
23  
24  #[derive(serde::Deserialize, Debug, Clone, clap::Args, Default, Nested)]
25  struct Logging {
26      level: String,
27  
28      #[arg(short)]
29      colors: bool,
30  }
31  
32  fn main() {
33      let config = ConfigLoader::default()
34          .with_env_prefix("KONFIK")
35          .with_config_file("app.toml")
36          .with_validation(|config| {
37              if let Some(port) = config
38                  .get("port")
39                  .and_then(serde_json::value::Value::as_u64)
40              {
41                  if port > 65535 {
42                      return Err(Error::Validation("Invalid port".to_string()));
43                  }
44              }
45              Ok(())
46          })
47          .load_with_cli::<AppConfig>();
48  
49      let _config = match config {
50          Ok(cfg) => {
51              println!("{cfg:#?}");
52              cfg
53          }
54          Err(e) => {
55              eprintln!("{e}");
56              return;
57          }
58      };
59  }