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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
//! Core types that define how clapfig discovers, resolves, and persists configuration.
//!
//! Configuration lookup has three orthogonal axes, each controlled independently
//! on the builder:
//!
//! | Axis | Builder method | Controls |
//! |------|---------------|----------|
//! | **Discovery** | [`search_paths()`] | Where to look for config files |
//! | **Resolution** | [`search_mode()`] | Whether to merge all found files or pick one |
//! | **Persistence** | [`persist_scope()`] | Named targets for `config set` writes |
//!
//! [`search_paths()`]: crate::ClapfigBuilder::search_paths
//! [`search_mode()`]: crate::ClapfigBuilder::search_mode
//! [`persist_scope()`]: crate::ClapfigBuilder::persist_scope
//!
//! # Discovery: [`SearchPath`]
//!
//! A search path is a source of candidate directories. The builder accepts a list
//! of them in **priority-ascending order** — the last entry has the highest priority.
//!
//! Most variants resolve to a single directory (`Platform`, `Home`, `Cwd`, `Path`).
//! The [`Ancestors`](SearchPath::Ancestors) variant is special: it expands inline
//! into multiple directories by walking up from the current working directory,
//! emitting ancestors from shallowest (root) to deepest (CWD) so that deeper
//! directories have higher priority.
//!
//! # Resolution: [`SearchMode`]
//!
//! Controls what happens once candidate directories have been searched:
//!
//! - **[`Merge`](SearchMode::Merge)** (default): All found config files are loaded
//! and deep-merged. Later (higher-priority) files override earlier ones. This is
//! the classic layered-config pattern: a global config provides defaults and a
//! project-local config overrides specific keys.
//!
//! - **[`FirstMatch`](SearchMode::FirstMatch)**: Only the single highest-priority
//! file found is used. The search starts from the highest-priority end and stops
//! at the first hit. This is the "find my config" pattern: a tool looks in several
//! places and uses whichever config it finds first.
//!
//! Both modes use the same priority ordering — you never need to reorder your search
//! paths when switching modes.
//!
//! # Common patterns
//!
//! **Layered global + local** (Merge, default): A CLI app that reads a global config
//! from the platform directory and merges project-local overrides from the working
//! directory. A user sets their preferred theme globally; a project overrides the
//! output format.
//!
//! **Fallback chain** (FirstMatch + explicit paths): A code formatter that looks
//! for a config in the project directory first, then the user's home, then the
//! platform directory. The first config found is used as-is — no merging.
//!
//! **Nearest project config** (FirstMatch + Ancestors): A build tool invoked from
//! a subdirectory walks up the tree to find the nearest project config. Stops at
//! the repository root (`.git` marker).
//!
//! **Per-directory layering** (Merge + Ancestors): An editor plugin that collects
//! style configs from every ancestor directory and merges them, with deeper
//! directories taking precedence — like `.editorconfig`.
use PathBuf;
/// A configuration layer in the merge pipeline.
///
/// Used with [`ClapfigBuilder::layer_order()`](crate::ClapfigBuilder::layer_order)
/// to customize the precedence of configuration sources.
///
/// The default order is `[Files, Env, Url, Cli]` (lowest to highest priority).
/// Layers listed later in the order override earlier ones.
///
/// # Example
///
/// ```ignore
/// use clapfig::{Clapfig, Layer};
///
/// // Make files override env vars instead of the default
/// let config: AppConfig = Clapfig::builder()
/// .app_name("myapp")
/// .layer_order(vec![Layer::Env, Layer::Files, Layer::Cli])
/// .load()?;
/// ```
/// Where to search for config files.
///
/// Each variant represents a source of candidate directories. The builder
/// accepts a `Vec<SearchPath>` in priority-ascending order: last = highest
/// priority.
///
/// Most variants resolve to a single directory. [`Ancestors`](Self::Ancestors)
/// expands into multiple directories by walking up from the current working
/// directory. See the [module documentation](self) for details.
/// Controls where an [`Ancestors`](SearchPath::Ancestors) walk stops.
///
/// The walk always starts at the current working directory and moves toward
/// the filesystem root. The boundary determines where it ends.
/// How found config files are resolved into configuration.
///
/// Controls what happens after [`SearchPath`] entries have been expanded into
/// directories and checked for config files. Both modes use the same
/// priority-ascending ordering — the search path list does not need to change
/// when switching modes.
///
/// See the [module-level documentation](self) for use-case examples.
/// A config operation, independent of any CLI framework.
/// The CLI layer converts parsed clap args into this.
///
/// Operations that target a specific config file accept an optional `scope` name.
/// When `scope` is `None`:
/// - **`List` / `Get`**: return the merged resolved configuration (all layers).
/// - **`Set` / `Unset`**: write to the default (first) persist scope.
///
/// When `scope` is `Some(name)`:
/// - **`List` / `Get`**: return entries from that scope's config file only.
/// - **`Set` / `Unset`**: write to that scope's config file.