1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
//! Public schema write APIs.
use Path;
use JsonSchema;
use crate::;
use ;
/// Writes a Draft 7 JSON Schema for the root config type.
///
/// The same generated schema can be referenced from TOML, YAML, JSON, and JSON5
/// configuration files. TOML and YAML templates bind it with editor directives.
/// JSON and JSON5 templates bind it with a top-level `$schema` property.
/// Generated schemas omit JSON Schema `required` constraints so editors provide
/// completion without requiring every config field to exist in each partial
/// config file.
///
/// # Type Parameters
///
/// - `S`: Config schema type that derives [`JsonSchema`].
///
/// # Arguments
///
/// - `output_path`: Destination path for the generated JSON Schema.
///
/// # Returns
///
/// Returns `Ok(())` after the schema file has been written.
///
/// # Examples
///
/// ```
/// use confique::Config;
/// use rust_config_tree::config::write_config_schema;
/// use schemars::JsonSchema;
///
/// #[derive(Config, JsonSchema, rust_config_tree::ConfigSchema)]
/// struct AppConfig {
/// #[config(default = [])]
/// include: Vec<std::path::PathBuf>,
/// #[config(default = "demo")]
/// mode: String,
/// }
///
/// let path = std::env::temp_dir().join("rust-config-tree-write-schema-doctest.json");
/// write_config_schema::<AppConfig>(&path)?;
///
/// assert!(path.exists());
/// # let _ = std::fs::remove_file(path);
/// # Ok::<(), rust_config_tree::error::ConfigError>(())
/// ```
/// Collects the root schema and section schemas for a config type.
///
/// The root schema is written to `output_path`. Nested `confique` sections are
/// written next to it as `<section>.schema.json` when the nested field schema
/// has `x-tree-split = true`; deeper split sections are nested in matching
/// directories, for example `schemas/outer/inner.schema.json`. Each generated
/// schema contains only the fields for its own template file; split child
/// section fields are omitted and completed by their own section schemas.
///
/// # Type Parameters
///
/// - `S`: Config schema type that derives [`JsonSchema`] and exposes section
/// metadata through [`ConfigSchema`].
///
/// # Arguments
///
/// - `output_path`: Destination path for the root JSON Schema.
///
/// # Returns
///
/// Returns all generated schema targets in traversal order.
///
/// # Examples
///
/// ```
/// use confique::Config;
/// use rust_config_tree::config::config_schema_targets_for_path;
/// use schemars::JsonSchema;
///
/// #[derive(Config, JsonSchema, rust_config_tree::ConfigSchema)]
/// struct AppConfig {
/// #[config(default = [])]
/// include: Vec<std::path::PathBuf>,
/// #[config(default = "demo")]
/// mode: String,
/// }
///
/// let targets = config_schema_targets_for_path::<AppConfig>("schemas/config.schema.json")?;
///
/// assert_eq!(targets.len(), 1);
/// assert!(targets[0].content.contains("\"mode\""));
/// # Ok::<(), rust_config_tree::error::ConfigError>(())
/// ```
/// Writes the root schema and section schemas for a config type.
///
/// Parent directories are created before each schema is written. Generated
/// schemas omit JSON Schema `required` constraints so they can be used for IDE
/// completion against partial config files. The root schema does not complete
/// split nested section fields.
///
/// # Type Parameters
///
/// - `S`: Config schema type that derives [`JsonSchema`] and exposes section
/// metadata through [`ConfigSchema`].
///
/// # Arguments
///
/// - `output_path`: Destination path for the root JSON Schema.
///
/// # Returns
///
/// Returns `Ok(())` after all schema files have been written.
///
/// # Examples
///
/// ```
/// use confique::Config;
/// use rust_config_tree::config::write_config_schemas;
/// use schemars::JsonSchema;
///
/// #[derive(Config, JsonSchema, rust_config_tree::ConfigSchema)]
/// struct AppConfig {
/// #[config(default = [])]
/// include: Vec<std::path::PathBuf>,
/// #[config(default = "demo")]
/// mode: String,
/// }
///
/// let path = std::env::temp_dir()
/// .join("rust-config-tree-write-schemas-doctest")
/// .join("config.schema.json");
/// write_config_schemas::<AppConfig>(&path)?;
///
/// assert!(path.exists());
/// # let _ = std::fs::remove_file(&path);
/// # if let Some(parent) = path.parent() { let _ = std::fs::remove_dir_all(parent); }
/// # Ok::<(), rust_config_tree::error::ConfigError>(())
/// ```