aboutsummaryrefslogtreecommitdiff
path: root/internal/cond/types.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-12 01:22:12 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-12 01:22:12 +0200
commit3b36a48b7ce5a53a9366f3b31f94311f178e2553 (patch)
treeecbb277ff916b719f2ee45fba017792b85d5faf9 /internal/cond/types.go
parent42b02c47be9b285099203e44a2570636d4ca6f03 (diff)
downloadkrino-3b36a48b7ce5a53a9366f3b31f94311f178e2553.tar.gz
krino-3b36a48b7ce5a53a9366f3b31f94311f178e2553.zip
krino: matching — scan, ignore, conditions, extraction, duplicates, explain, dry run
Diffstat (limited to 'internal/cond/types.go')
-rw-r--r--internal/cond/types.go111
1 files changed, 111 insertions, 0 deletions
diff --git a/internal/cond/types.go b/internal/cond/types.go
new file mode 100644
index 0000000..81c2f45
--- /dev/null
+++ b/internal/cond/types.go
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+// Package cond compiles the s-expression conditions of a rule's (when ...)
+// into a tree that Task 8's evaluator walks against one file's facts.
+package cond
+
+import (
+ "regexp"
+ "time"
+
+ "krino/internal/sexp"
+)
+
+// Options carries a rule's resolved case and fold settings into compilation.
+type Options struct {
+ IgnoreCase bool // the rule's resolved case setting is "ignore"
+ Fold bool // the rule's resolved fold setting
+}
+
+// Cond is a compiled condition. A Cond compiled from no conditions (a rule
+// without when) is always true.
+type Cond struct {
+ root *node // nil: always true
+ opt Options // the case/fold settings conditions were compiled with; Task 8 needs them again at eval time
+ UsesContent bool // some content test exists
+ DupDirs [][]string // the raw directory arguments of each duplicate test, in order
+}
+
+// kind is what a compiled node tests, or how it combines its children.
+type kind int
+
+const (
+ kAnd kind = iota
+ kOr
+ kNot
+ kType
+ kName
+ kPath
+ kContent
+ kSize
+ kAge
+ kDuplicate
+ kMatched
+)
+
+// Costs, per the brief's cost order: cheapest first when sorting and/or
+// children. not takes its child's cost; and/or take the sum of theirs.
+const (
+ costCheap = 1 // type, size, age, matched
+ costRegex = 2 // name, path
+ costDuplicate = 5
+ costContent = 10
+)
+
+// pattern is one name/path regex, compiled and paired with the text it was
+// written as (undecorated by (?i) or folding), for labels and reasons.
+type pattern struct {
+ re *regexp.Regexp
+ src string
+}
+
+// keyword is one content keyword, normalised for matching and paired with
+// the text it was written as, for labels and reasons.
+type keyword struct {
+ norm string
+ src string
+}
+
+// node is one compiled condition: a leaf test, or an and/or/not combinator
+// over other nodes. Task 8 evaluates this tree.
+type node struct {
+ kind kind
+ pos sexp.Pos // the position of the node as written, for diagnostics
+ label string // the test as written, e.g. `content "acme ltd" "0000000000"`
+ cost int // this node's evaluation cost; and/or sort children by it
+ children []*node // and, or, not
+
+ // type
+ suffixes []string // leading-dot, lower-case, e.g. ".pdf"
+
+ // name, path
+ patterns []pattern
+
+ // content
+ keywords []keyword
+
+ // size, age (kind tells which is populated)
+ op string
+ sizeVal int64
+ ageVal time.Duration
+
+ // duplicate
+ dirs []string
+}
+
+// groups maps a (type ...) group name to the extensions it expands to,
+// spec Appendix A.
+var groups = map[string][]string{
+ "image": {"jpg", "jpeg", "png", "gif", "webp", "bmp", "tif", "tiff", "heic", "heif", "avif", "svg", "ico", "raw", "cr2", "nef", "arw", "dng"},
+ "video": {"mp4", "mkv", "webm", "mov", "avi", "m4v", "mpg", "mpeg", "wmv", "flv", "3gp"},
+ "audio": {"mp3", "flac", "ogg", "opus", "m4a", "aac", "wav", "wma", "aiff"},
+ "archive": {"zip", "tar", "gz", "tgz", "bz2", "tbz2", "xz", "txz", "zst", "7z", "rar", "lz", "lzma", "cpio"},
+ "document": {"pdf", "doc", "docx", "odt", "rtf", "txt", "md", "tex"},
+ "spreadsheet": {"xls", "xlsx", "ods", "csv", "tsv"},
+ "presentation": {"ppt", "pptx", "odp"},
+ "ebook": {"epub", "mobi", "azw", "azw3", "fb2", "djvu"},
+ "code": {"go", "c", "h", "cpp", "hpp", "py", "sh", "js", "ts", "rs", "java", "rb", "pl", "lua", "html", "css", "json", "yaml", "yml", "toml", "xml", "sql"},
+ "text": {"txt", "md", "log", "csv", "tsv", "json", "yaml", "yml", "toml", "xml", "ini", "conf"},
+ "package": {"deb", "rpm", "apk", "appimage", "exe", "msi", "flatpak", "snap"},
+ "font": {"ttf", "otf", "woff", "woff2"},
+}