Skip to main content

transparent_array_section/
transparent_array_section.rs

1//! Generates templates and schemas for a config with transparent array sections.
2//!
3//! Run from the repository root:
4//!
5//! ```bash
6//! cargo run --example transparent_array_section
7//! ```
8//!
9//! Template generation for transparent split sections uses
10//! `template_targets_for_paths` or `write_config_templates`. See
11//! `manual/en/ide-completions.md` for the full workflow.
12
13use std::{
14    fs, io,
15    path::PathBuf,
16    time::{SystemTime, UNIX_EPOCH},
17};
18
19use confique::Config;
20use rust_config_tree::{
21    ConfigSchema,
22    config::{load_config, write_config_schemas},
23    transparent_array_section,
24};
25use schemars::JsonSchema;
26
27transparent_array_section! {
28    /// Child declarations stored as a transparent array section.
29    pub struct ChildrenSection {
30        #[config(default = [{ "name": "worker" }])]
31        pub items: Vec<ChildDeclaration>,
32    }
33}
34
35/// One child declaration used by the example config schema.
36#[derive(Debug, Clone, PartialEq, Config, JsonSchema, serde::Serialize, serde::Deserialize)]
37pub struct ChildDeclaration {
38    /// Child name.
39    pub name: String,
40}
41
42/// Root config schema used by the transparent array section example.
43#[derive(Debug, Clone, PartialEq, Config, JsonSchema, ConfigSchema)]
44pub struct AppConfig {
45    /// Included child configuration files.
46    #[config(default = [])]
47    pub include: Vec<PathBuf>,
48
49    /// Root scalar value.
50    #[config(default = "demo")]
51    pub mode: String,
52
53    /// Transparent child declarations split into `children.yaml`.
54    #[config(nested)]
55    #[schemars(extend(
56        "x-tree-split" = true,
57        "x-tree-transparent-array" = true
58    ))]
59    pub children: ChildrenSection,
60}
61
62/// Writes demo files, generates schemas/templates, loads split config, and prints results.
63fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
64    let dir = temp_example_dir("transparent-array-section")?;
65    let root = dir.join("config.yaml");
66    let schema = dir.join("app.schema.json");
67    let children = dir.join("children.yaml");
68
69    fs::write(&root, "include:\n  - children.yaml\nmode: demo\n")?;
70    fs::write(&children, "- name: api\n")?;
71
72    write_config_schemas::<AppConfig>(&schema)?;
73    println!("schema: {}", schema.display());
74
75    let config = load_config::<AppConfig>(&root)?;
76    println!("loaded children: {}", config.children.len());
77    assert_eq!(config.children.items[0].name, "api");
78
79    println!("split file: {}", children.display());
80
81    let _ = fs::remove_dir_all(dir);
82    Ok(())
83}
84
85/// Creates a unique temporary directory for one example run.
86fn temp_example_dir(name: &str) -> io::Result<PathBuf> {
87    let nanos = SystemTime::now()
88        .duration_since(UNIX_EPOCH)
89        .unwrap_or_default()
90        .as_nanos();
91    let dir = std::env::temp_dir().join(format!("rust-config-tree-{name}-{nanos}"));
92    fs::create_dir_all(&dir)?;
93    Ok(dir)
94}