Scanner
The scanner walks a directory tree, filters files by extension and exclude patterns, reads content, and delegates to the parser for TODO extraction.
Scanner
#![allow(unused)] fn main() { pub struct Scanner { parser: Parser, config: ParsingConfig, } }
Constructor
#![allow(unused)] fn main() { pub fn new(config: ParsingConfig) -> Result<Self, TowlScannerError> }
Creates a new scanner. Compiles all regex patterns from the config during construction so pattern errors are caught early.
scan
#![allow(unused)] fn main() { pub async fn scan(&self, path: PathBuf) -> Result<ScanResult, TowlScannerError> }
Recursively scans path for TODO comments. Returns a ScanResult on success.
Behaviour:
- Validates the path (rejects path traversal)
- Walks the directory using the
ignorecrate (respects.gitignore) - Filters files by extension (
file_extensionsconfig) - Skips files matching
exclude_patterns - Skips files larger than
MAX_FILE_SIZE(10 MB) - Reads and parses each file asynchronously via
tokio::fs - Collects results until a resource limit is reached or the walk completes
Errors:
InvalidPath-- Path contains traversal components (..)FileTooLarge-- File exceeds 10 MBTooManyTodos-- Single file exceeds 10,000 TODOsTooManyFiles-- Walk exceeds 100,000 filesUnableToReadFileAtPath-- I/O error reading a specific fileUnableToWalkFile-- Directory walk errorParsingError-- Regex or parsing failure (propagated from parser)
ScanResult
#![allow(unused)] fn main() { pub struct ScanResult { pub todos: Vec<TodoComment>, pub files_scanned: usize, pub files_skipped: usize, pub files_errored: usize, pub duration: std::time::Duration, } }
Methods
#![allow(unused)] fn main() { pub const fn all_files_failed(&self) -> bool }
Returns true when files_scanned == 0 and files_errored > 0. Indicates a likely permissions or path issue where no files could be read.
#![allow(unused)] fn main() { pub const fn is_clean(&self) -> bool }
Returns true when todos is empty and files_errored == 0. A clean scan with no issues.
Resource Limits
| Constant | Value | Trigger |
|---|---|---|
MAX_FILE_SIZE | 10,485,760 bytes (10 MB) | File skipped |
MAX_TODO_COUNT | 10,000 | Error for that file |
MAX_TOTAL_TODO_COUNT | 100,000 | Scan stops, returns partial |
MAX_FILES_SCANNED | 100,000 | Scan stops, returns partial |
Example
#![allow(unused)] fn main() { use towl::config::ParsingConfig; use towl::scanner::Scanner; use std::path::PathBuf; let config = ParsingConfig::default(); let scanner = Scanner::new(config)?; let result = scanner.scan(PathBuf::from(".")).await?; println!("Found {} TODOs in {} files", result.todos.len(), result.files_scanned); if result.all_files_failed() { eprintln!("Warning: no files could be read"); } }