diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-12 01:22:12 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-12 01:22:12 +0200 |
| commit | 3b36a48b7ce5a53a9366f3b31f94311f178e2553 (patch) | |
| tree | ecbb277ff916b719f2ee45fba017792b85d5faf9 /internal/cond/types.go | |
| parent | 42b02c47be9b285099203e44a2570636d4ca6f03 (diff) | |
| download | krino-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.go | 111 |
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"}, +} |
