docscanner/internal/analyzer/analyzer.go
type Analyzer interface {
Supports(filename string) bool
Analyze(filepath string, data []byte) (*model.ScanResult, error)
}Supportsdecides, based on filename/extension, whether this analyzer owns the file.Analyzereceives the full file contents as a[]byteplus the path.- Each analyzer returns a
*model.ScanResultdescribing its findings.
- New analyzers live in
internal/analyzer/and implement this interface. - The worker pool only depends on the interface, so adding new analyzers does not change concurrency code.
We can plug in Excel, PowerPoint, archives, binaries—anything—behind this interface.
main.go
└─ builds []Analyzer { WordAnalyzer, PDFAnalyzer, ... }
↓
StartWorkerPool (workerpool.go)
└─ receives []Analyzer and, for each file:
├─ a.Supports(file)
└─ a.Analyze(file, data) → *ScanResult
The rest of the system (CLI, worker pool, directory walker) only knows the Analyzer interface, not concrete implementations. This keeps code structure simple and makes it obvious where to plug in new behavior.