1use std::{
4 fs, io,
5 path::{Path, PathBuf},
6 time::{SystemTime, UNIX_EPOCH},
7};
8
9use rust_config_tree::tree::{ConfigSource, ConfigTreeOptions, IncludeOrder, load_config_tree};
10
11fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
13 let root_config = write_demo_tree()?;
14 let tree = load_config_tree(&root_config, load_source)?;
15
16 println!("declared order:");
17 for node in tree.nodes() {
18 println!("{} -> {:?}", node.path().display(), node.includes());
19 }
20
21 let reverse_tree = ConfigTreeOptions::default()
22 .include_order(IncludeOrder::Reverse)
23 .load(&root_config, load_source)?;
24
25 println!("reverse sibling order:");
26 for value in reverse_tree.into_values() {
27 println!("{}", value.lines().next().unwrap_or_default());
28 }
29
30 Ok(())
31}
32
33fn load_source(path: &Path) -> io::Result<ConfigSource<String>> {
35 let content = fs::read_to_string(path)?;
36 let includes = content
37 .lines()
38 .filter_map(|line| line.strip_prefix("include="))
39 .map(PathBuf::from)
40 .collect();
41
42 Ok(ConfigSource::new(content, includes))
43}
44
45fn write_demo_tree() -> io::Result<PathBuf> {
47 let dir = temp_example_dir("tree-api")?;
48 let config_dir = dir.join("config");
49 fs::create_dir_all(&config_dir)?;
50
51 let root_config = dir.join("root.conf");
52 fs::write(
53 &root_config,
54 "root\ninclude=config/database.conf\ninclude=config/server.conf\n",
55 )?;
56 fs::write(config_dir.join("database.conf"), "database\npool_size=16\n")?;
57 fs::write(config_dir.join("server.conf"), "server\nport=3000\n")?;
58
59 Ok(root_config)
60}
61
62fn temp_example_dir(name: &str) -> io::Result<PathBuf> {
64 let nanos = SystemTime::now()
65 .duration_since(UNIX_EPOCH)
66 .unwrap_or_default()
67 .as_nanos();
68 let dir = std::env::temp_dir().join(format!("rust-config-tree-{name}-{nanos}"));
69 fs::create_dir_all(&dir)?;
70 Ok(dir)
71}