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");
}
}