Skip to main content

basic_loading/
basic_loading.rs

1//! Loads a root YAML config plus one included child file into a `confique`
2//! schema.
3
4use std::{
5    fs, io,
6    path::PathBuf,
7    time::{SystemTime, UNIX_EPOCH},
8};
9
10use confique::Config;
11use rust_config_tree::ConfigSchema;
12use rust_config_tree::config::load_config;
13use schemars::JsonSchema;
14
15#[derive(Debug, Config, JsonSchema, ConfigSchema)]
16struct AppConfig {
17    #[config(default = [])]
18    include: Vec<PathBuf>,
19
20    #[config(default = "paper")]
21    mode: String,
22
23    #[config(nested)]
24    server: ServerConfig,
25}
26
27#[derive(Debug, Config, JsonSchema)]
28struct ServerConfig {
29    #[config(default = "127.0.0.1")]
30    #[config(env = "APP_SERVER_BIND")]
31    bind: String,
32
33    #[config(default = 8080)]
34    #[config(env = "APP_SERVER_PORT")]
35    port: u16,
36}
37
38/// Writes demo files, loads them, and prints the merged config.
39fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
40    let root_config = write_demo_config()?;
41    let config = load_config::<AppConfig>(&root_config)?;
42
43    println!("config path: {}", root_config.display());
44    println!("include count: {}", config.include.len());
45    println!("mode: {}", config.mode);
46    println!("server bind: {}", config.server.bind);
47    println!("server port: {}", config.server.port);
48
49    Ok(())
50}
51
52/// Creates a root config file and one included child file for the example.
53fn write_demo_config() -> io::Result<PathBuf> {
54    let dir = temp_example_dir("basic-loading")?;
55    let config_dir = dir.join("config");
56    fs::create_dir_all(&config_dir)?;
57
58    let root_config = dir.join("config.yaml");
59    fs::write(
60        &root_config,
61        r#"
62include:
63  - config/server.yaml
64
65mode: demo
66"#
67        .trim_start(),
68    )?;
69
70    fs::write(
71        config_dir.join("server.yaml"),
72        r#"
73server:
74  bind: 0.0.0.0
75  port: 3000
76"#
77        .trim_start(),
78    )?;
79
80    Ok(root_config)
81}
82
83/// Creates a unique temporary directory for one example run.
84fn temp_example_dir(name: &str) -> io::Result<PathBuf> {
85    let nanos = SystemTime::now()
86        .duration_since(UNIX_EPOCH)
87        .unwrap_or_default()
88        .as_nanos();
89    let dir = std::env::temp_dir().join(format!("rust-config-tree-{name}-{nanos}"));
90    fs::create_dir_all(&dir)?;
91    Ok(dir)
92}