gts_validator/config.rs
1//! Configuration types for GTS validation.
2//!
3//! Split into core validation config (universal) and source-specific config
4//! (how content is discovered). This ensures the core API does not leak
5//! filesystem concerns.
6
7use std::path::PathBuf;
8
9/// Vendor matching policy for GTS ID validation.
10#[derive(Debug, Clone, Default)]
11#[non_exhaustive]
12pub enum VendorPolicy {
13 /// Accept any vendor (no vendor enforcement).
14 #[default]
15 Any,
16 /// All GTS IDs must match this exact vendor (example vendors are always tolerated).
17 MustMatch(String),
18 /// All GTS IDs must match one of the listed vendors (example vendors are always tolerated).
19 AllowList(Vec<String>),
20}
21
22/// Controls how GTS identifier candidates are discovered in markdown files.
23#[derive(Debug, Clone, Default, PartialEq, Eq)]
24#[non_exhaustive]
25pub enum DiscoveryMode {
26 /// Only match well-formed GTS patterns — fewer false positives (default).
27 #[default]
28 StrictSpecOnly,
29 /// Permissive regex catches ALL gts.* strings including malformed IDs.
30 /// Use for strict CI enforcement where every malformed ID must be reported.
31 Heuristic,
32}
33
34/// Core validation config — applies regardless of input source.
35#[derive(Debug, Clone, Default)]
36#[non_exhaustive]
37pub struct ValidationConfig {
38 /// Vendor matching policy for all GTS IDs.
39 /// Example vendors (acme, globex, etc.) are always tolerated regardless of policy.
40 pub vendor_policy: VendorPolicy,
41 /// Scan JSON/YAML object keys for GTS identifiers (default: off).
42 pub scan_keys: bool,
43 /// Discovery mode for markdown scanning.
44 ///
45 /// - `StrictSpecOnly` (default): only well-formed GTS patterns are discovered.
46 /// - `Heuristic`: a permissive regex catches ALL gts.* strings, including malformed IDs.
47 pub discovery_mode: DiscoveryMode,
48 /// Additional skip tokens for markdown scanning.
49 /// If any of these strings appear before a GTS candidate on the same line,
50 /// validation is skipped for that candidate. Case-insensitive matching.
51 /// Example: `vec!["**given**".to_owned()]` to skip BDD-style bold formatting.
52 pub skip_tokens: Vec<String>,
53}
54
55/// Filesystem-specific source options.
56///
57/// NOTE: `paths` is required and must be non-empty. Default scan roots
58/// (e.g. `docs/modules/libs/examples`) are a CLI/wrapper concern, not
59/// baked into the library — keeps `gts-validator` repo-layout-agnostic.
60#[derive(Debug, Clone)]
61#[non_exhaustive]
62pub struct FsSourceConfig {
63 /// Paths to scan (files or directories). Required, must be non-empty.
64 pub paths: Vec<PathBuf>,
65 /// Exclude patterns (glob format).
66 pub exclude: Vec<String>,
67 /// Maximum file size in bytes (default: 10 MB).
68 pub max_file_size: u64,
69 /// Whether to follow symbolic links.
70 ///
71 /// **Defaults to `false`** — following symlinks allows escaping the repository
72 /// root, traversing system directories, and reading secrets in CI environments.
73 /// Only enable if you explicitly trust all symlinks in the repository.
74 pub follow_links: bool,
75 /// Maximum directory traversal depth (default: 64).
76 /// Prevents infinite recursion via deeply nested symlinks or directories.
77 pub max_depth: usize,
78 /// Maximum total number of files to scan (default: `100_000`).
79 /// Prevents memory exhaustion on pathological repositories.
80 pub max_files: usize,
81 /// Maximum total bytes to read across all files (default: 512 MB).
82 /// Prevents memory exhaustion when many large files are present.
83 pub max_total_bytes: u64,
84}
85
86impl Default for FsSourceConfig {
87 fn default() -> Self {
88 Self {
89 paths: Vec::new(),
90 exclude: Vec::new(),
91 max_file_size: 10_485_760,
92 follow_links: false,
93 max_depth: 64,
94 max_files: 100_000,
95 max_total_bytes: 536_870_912,
96 }
97 }
98}