Skip to main content

evault_core/traits/
scanner.rs

1//! [`CodeScanner`] — find references to environment variables in source code.
2
3use std::path::{Path, PathBuf};
4
5use crate::error::ScannerError;
6
7/// Where a scanner found a variable reference.
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct ScanHit {
10    /// File the reference was found in.
11    pub path: PathBuf,
12    /// 1-based line number of the reference.
13    ///
14    /// Lines are split on `\n` and `\r\n`. Files that use only bare `\r`
15    /// line endings (legacy Mac OS Classic) are treated as a single line;
16    /// implementations should document this in their own docs if relevant.
17    pub line: usize,
18    /// 1-based **character** column where the reference begins (Unicode
19    /// scalar values, not bytes). Editors universally count columns in
20    /// characters, so a hit at column `N` lands where a user clicking
21    /// `goto N` would expect, even if the line contains multi-byte UTF-8
22    /// before the match.
23    pub column: usize,
24    /// Variable name as it appears in the code (e.g. `DATABASE_URL`).
25    pub name: String,
26}
27
28/// Walk a directory tree looking for references to environment variables.
29///
30/// Implementations should:
31/// - skip common build/output directories (`target`, `node_modules`, `dist`, …);
32/// - skip binary files (no UTF-8) without error;
33/// - return one [`ScanHit`] per reference (a variable referenced N times in
34///   one file produces N hits).
35pub trait CodeScanner: Send + Sync {
36    /// Scan the directory rooted at `root` and return all hits.
37    ///
38    /// # Errors
39    /// Returns [`ScannerError::Io`] if the file system cannot be walked;
40    /// [`ScannerError::Pattern`] if the configured patterns are invalid.
41    fn scan(&self, root: &Path) -> Result<Vec<ScanHit>, ScannerError>;
42}