Skip to main content

tokmd_settings/
config.rs

1//! TOML configuration file contracts.
2
3use std::collections::BTreeMap;
4use std::path::Path;
5
6use serde::{Deserialize, Serialize};
7
8/// Root TOML configuration structure.
9#[derive(Debug, Clone, Default, Serialize, Deserialize)]
10#[serde(default)]
11pub struct TomlConfig {
12    /// Scan settings (applies to all commands).
13    pub scan: ScanConfig,
14
15    /// Module command settings.
16    pub module: ModuleConfig,
17
18    /// Export command settings.
19    pub export: ExportConfig,
20
21    /// Analyze command settings.
22    pub analyze: AnalyzeConfig,
23
24    /// Context command settings.
25    pub context: ContextConfig,
26
27    /// Badge command settings.
28    pub badge: BadgeConfig,
29
30    /// Gate command settings.
31    pub gate: GateConfig,
32
33    /// Named view profiles (e.g., [view.llm], [view.ci]).
34    #[serde(default)]
35    pub view: BTreeMap<String, ViewProfile>,
36}
37
38/// Scan settings shared by all commands.
39#[derive(Debug, Clone, Default, Serialize, Deserialize)]
40#[serde(default)]
41pub struct ScanConfig {
42    /// Paths to scan (default: ["."])
43    pub paths: Option<Vec<String>>,
44
45    /// Glob patterns to exclude.
46    pub exclude: Option<Vec<String>>,
47
48    /// Include hidden files and directories.
49    pub hidden: Option<bool>,
50
51    /// Config file strategy for tokei: "auto" or "none".
52    pub config: Option<String>,
53
54    /// Disable all ignore files.
55    pub no_ignore: Option<bool>,
56
57    /// Disable parent directory ignore file traversal.
58    pub no_ignore_parent: Option<bool>,
59
60    /// Disable .ignore/.tokeignore files.
61    pub no_ignore_dot: Option<bool>,
62
63    /// Disable .gitignore files.
64    pub no_ignore_vcs: Option<bool>,
65
66    /// Treat doc comments as comments instead of code.
67    pub doc_comments: Option<bool>,
68}
69
70/// Module command settings.
71#[derive(Debug, Clone, Default, Serialize, Deserialize)]
72#[serde(default)]
73pub struct ModuleConfig {
74    /// Root directories for module grouping.
75    pub roots: Option<Vec<String>>,
76
77    /// Depth for module grouping.
78    pub depth: Option<usize>,
79
80    /// Children handling: "collapse" or "separate".
81    pub children: Option<String>,
82}
83
84/// Export command settings.
85#[derive(Debug, Clone, Default, Serialize, Deserialize)]
86#[serde(default)]
87pub struct ExportConfig {
88    /// Minimum lines of code to include.
89    pub min_code: Option<usize>,
90
91    /// Maximum rows in output.
92    pub max_rows: Option<usize>,
93
94    /// Redaction mode: "none", "paths", or "all".
95    pub redact: Option<String>,
96
97    /// Output format: "jsonl", "csv", "json", "cyclonedx".
98    pub format: Option<String>,
99
100    /// Children handling: "collapse" or "separate".
101    pub children: Option<String>,
102}
103
104/// Analyze command settings.
105#[derive(Debug, Clone, Default, Serialize, Deserialize)]
106#[serde(default)]
107pub struct AnalyzeConfig {
108    /// Analysis preset.
109    pub preset: Option<String>,
110
111    /// Context window size for utilization analysis.
112    pub window: Option<usize>,
113
114    /// Output format.
115    pub format: Option<String>,
116
117    /// Force git metrics on/off.
118    pub git: Option<bool>,
119
120    /// Max files for asset/deps/content scans.
121    pub max_files: Option<usize>,
122
123    /// Max total bytes for content scans.
124    pub max_bytes: Option<u64>,
125
126    /// Max bytes per file for content scans.
127    pub max_file_bytes: Option<u64>,
128
129    /// Max commits for git metrics.
130    pub max_commits: Option<usize>,
131
132    /// Max files per commit for git metrics.
133    pub max_commit_files: Option<usize>,
134
135    /// Import graph granularity: "module" or "file".
136    pub granularity: Option<String>,
137
138    /// Effort model for estimate calculations.
139    pub effort_model: Option<String>,
140
141    /// Effort report layer.
142    pub effort_layer: Option<String>,
143
144    /// Base reference for effort delta computation.
145    pub effort_base_ref: Option<String>,
146
147    /// Head reference for effort delta computation.
148    pub effort_head_ref: Option<String>,
149
150    /// Enable Monte Carlo uncertainty for effort estimation.
151    pub effort_monte_carlo: Option<bool>,
152
153    /// Monte Carlo iterations for effort estimation.
154    pub effort_mc_iterations: Option<usize>,
155
156    /// Monte Carlo seed for effort estimation.
157    pub effort_mc_seed: Option<u64>,
158}
159
160/// Context command settings.
161#[derive(Debug, Clone, Default, Serialize, Deserialize)]
162#[serde(default)]
163pub struct ContextConfig {
164    /// Token budget with optional k/m suffix.
165    pub budget: Option<String>,
166
167    /// Packing strategy: "greedy" or "spread".
168    pub strategy: Option<String>,
169
170    /// Ranking metric: "code", "tokens", "churn", "hotspot".
171    pub rank_by: Option<String>,
172
173    /// Output mode: "list", "bundle", "json".
174    pub output: Option<String>,
175
176    /// Strip blank lines from bundle output.
177    pub compress: Option<bool>,
178}
179
180/// Badge command settings.
181#[derive(Debug, Clone, Default, Serialize, Deserialize)]
182#[serde(default)]
183pub struct BadgeConfig {
184    /// Default metric for badges.
185    pub metric: Option<String>,
186}
187
188/// Gate command settings.
189#[derive(Debug, Clone, Default, Serialize, Deserialize)]
190#[serde(default)]
191pub struct GateConfig {
192    /// Path to policy file.
193    pub policy: Option<String>,
194
195    /// Path to baseline file for ratchet comparison.
196    pub baseline: Option<String>,
197
198    /// Analysis preset for compute-then-gate mode.
199    pub preset: Option<String>,
200
201    /// Fail fast on first error.
202    pub fail_fast: Option<bool>,
203
204    /// Inline policy rules.
205    pub rules: Option<Vec<GateRule>>,
206
207    /// Inline ratchet rules for baseline comparison.
208    pub ratchet: Option<Vec<RatchetRuleConfig>>,
209
210    /// Allow missing baseline values (treat as pass).
211    pub allow_missing_baseline: Option<bool>,
212
213    /// Allow missing current values (treat as pass).
214    pub allow_missing_current: Option<bool>,
215}
216
217/// A single ratchet rule for baseline comparison (TOML configuration).
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub struct RatchetRuleConfig {
220    /// JSON Pointer to the metric (e.g., "/complexity/avg_cyclomatic").
221    pub pointer: String,
222
223    /// Maximum allowed percentage increase from baseline.
224    #[serde(default)]
225    pub max_increase_pct: Option<f64>,
226
227    /// Maximum allowed absolute value (hard ceiling).
228    #[serde(default)]
229    pub max_value: Option<f64>,
230
231    /// Rule severity level: "error" (default) or "warn".
232    #[serde(default)]
233    pub level: Option<String>,
234
235    /// Human-readable description of the rule.
236    #[serde(default)]
237    pub description: Option<String>,
238}
239
240/// A single gate policy rule (for inline TOML configuration).
241#[derive(Debug, Clone, Serialize, Deserialize)]
242pub struct GateRule {
243    /// Human-readable name for the rule.
244    pub name: String,
245
246    /// JSON Pointer to the value to check (RFC 6901).
247    pub pointer: String,
248
249    /// Comparison operator.
250    pub op: String,
251
252    /// Single value for comparison.
253    #[serde(default)]
254    pub value: Option<serde_json::Value>,
255
256    /// Multiple values for "in" operator.
257    #[serde(default)]
258    pub values: Option<Vec<serde_json::Value>>,
259
260    /// Negate the result.
261    #[serde(default)]
262    pub negate: bool,
263
264    /// Rule severity level: "error" or "warn".
265    #[serde(default)]
266    pub level: Option<String>,
267
268    /// Custom failure message.
269    #[serde(default)]
270    pub message: Option<String>,
271}
272
273/// A named view profile that can override settings for specific use cases.
274#[derive(Debug, Clone, Default, Serialize, Deserialize)]
275#[serde(default)]
276pub struct ViewProfile {
277    // Shared settings
278    /// Output format.
279    pub format: Option<String>,
280
281    /// Show only top N rows.
282    pub top: Option<usize>,
283
284    // Lang settings
285    /// Include file counts in lang output.
286    pub files: Option<bool>,
287
288    // Module / Export settings
289    /// Module roots for grouping.
290    pub module_roots: Option<Vec<String>>,
291
292    /// Module depth for grouping.
293    pub module_depth: Option<usize>,
294
295    /// Minimum lines of code.
296    pub min_code: Option<usize>,
297
298    /// Maximum rows in output.
299    pub max_rows: Option<usize>,
300
301    /// Redaction mode.
302    pub redact: Option<String>,
303
304    /// Include metadata record.
305    pub meta: Option<bool>,
306
307    /// Children handling mode.
308    pub children: Option<String>,
309
310    // Analyze settings
311    /// Analysis preset.
312    pub preset: Option<String>,
313
314    /// Context window size.
315    pub window: Option<usize>,
316
317    // Context settings
318    /// Token budget.
319    pub budget: Option<String>,
320
321    /// Packing strategy.
322    pub strategy: Option<String>,
323
324    /// Ranking metric.
325    pub rank_by: Option<String>,
326
327    /// Output mode for context.
328    pub output: Option<String>,
329
330    /// Strip blank lines.
331    pub compress: Option<bool>,
332
333    // Badge settings
334    /// Badge metric.
335    pub metric: Option<String>,
336}
337
338impl TomlConfig {
339    /// Load configuration from a TOML string.
340    pub fn parse(s: &str) -> Result<Self, toml::de::Error> {
341        toml::from_str(s)
342    }
343
344    /// Load configuration from a file path.
345    pub fn from_file(path: &Path) -> std::io::Result<Self> {
346        let content = std::fs::read_to_string(path)?;
347        toml::from_str(&content)
348            .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
349    }
350}