Simple tool for automatic file management

ft: add Nickel file with definition of jobs structure

hauleth.dev ab7417d8 8129cf8d

verified
Changed files
+96
+96
ptsd.ncl
···
+
# SPDX-FileCopyrightText: 2024 Łukasz Niemier <#@hauleth.dev>
+
#
+
# SPDX-License-Identifier: EUPL-1.2
+
let Action = [|
+
'script String,
+
'move String,
+
'echo String,
+
'trash
+
|]
+
in
+
let NameMatch = [| 'exact String, 'wildcard String, 'regex String |] in
+
let FileType = [| 'dir, 'file, 'symlink |] in
+
let ContentMatch = [|
+
'mime String,
+
'magic {
+
offset | Number = 0,
+
bytes | (Array Number),
+
}
+
|]
+
in
+
let rec Filter = [|
+
'name NameMatch,
+
'file_type FileType,
+
'size [| 'less Number, 'equal Number, 'greater Number |],
+
'content_type ContentMatch,
+
'any (Array Filter),
+
'all (Array Filter),
+
'not Filter,
+
|]
+
in
+
{
+
Job = {
+
location
+
| String
+
| doc "Location that will be traversed for patterns",
+
filter
+
| Filter
+
| doc "File filters",
+
actions
+
| Array Action
+
| doc "Actions that should be applied to entry that matches pattern"
+
},
+
+
build | (Array Job) -> Dyn
+
=
+
let actionMatcher = match {
+
'script path => { script = path },
+
'move path => { move = path },
+
'echo msg => { echo = msg },
+
'trash => "trash",
+
}
+
in
+
let nameMatcher = match {
+
'exact val => { exact = val },
+
'wildcard val => { wildcard = val },
+
'regex val => { regex = val },
+
}
+
in
+
let rec filterMapper = match {
+
'name name => { type = "name" } & (nameMatcher name),
+
'file_type type => { type = "file_type", is = type },
+
'content_type type =>
+
type
+
|> match {
+
'mime mime => { type = "content_type", mime = mime },
+
'magic bytes => { type = "content_type", magic = bytes },
+
},
+
'size pred =>
+
let { tag, arg } = std.enum.to_tag_and_arg pred
+
in
+
{
+
type = "size",
+
size = arg,
+
ordering = tag,
+
},
+
'all allFilters =>
+
{
+
type = "all",
+
filters = std.array.map filterMapper allFilters
+
},
+
'any anyFilter =>
+
{
+
type = "any",
+
filters = std.array.map filterMapper anyFilter
+
},
+
}
+
in
+
let jobMapper = fun job =>
+
{
+
location = job.location,
+
filter = filterMapper job.filter,
+
actions = std.array.map actionMatcher job.actions,
+
}
+
in
+
std.array.map jobMapper
+
}