yaju-is-always-watching-you/internal/detector/detector.go
awayatan f47fef177b
Some checks failed
CI / test (push) Failing after 4s
Add yaju-is-always-watching-you: Forgejo goroku-check webhook bot
Watches issue/PR comments and pushes for flagged phrases; warns commenters
via reply and opens a redacted correction PR for flagged file content,
never rewriting history or deleting content directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 22:47:12 +09:00

51 lines
1.3 KiB
Go

// Package detector implements plain substring matching against a configured
// phrase list (the "goroku" list). Entries are literal fixed phrases rather
// than regexes because the source material is a closed set of copypasta
// lines, not a pattern language.
package detector
import "strings"
type Detector struct {
phrases []string
}
func New(phrases []string) *Detector {
uniq := make([]string, 0, len(phrases))
seen := make(map[string]struct{}, len(phrases))
for _, p := range phrases {
p = strings.TrimSpace(p)
if p == "" {
continue
}
if _, ok := seen[p]; ok {
continue
}
seen[p] = struct{}{}
uniq = append(uniq, p)
}
return &Detector{phrases: uniq}
}
// Detect returns every registered phrase found in text, in registration order.
func (d *Detector) Detect(text string) []string {
var found []string
for _, p := range d.phrases {
if strings.Contains(text, p) {
found = append(found, p)
}
}
return found
}
// Redact returns text with every matched phrase replaced by a same-width
// mask, along with the list of phrases that were matched.
func (d *Detector) Redact(text string) (string, []string) {
matched := d.Detect(text)
redacted := text
for _, p := range matched {
mask := strings.Repeat("○", len([]rune(p)))
redacted = strings.ReplaceAll(redacted, p, mask)
}
return redacted, matched
}