main
 1// gmailctl standard library
 2//
 3// This library contains utilities for common filter operations.
 4
 5{
 6  // chainFilters is a function that, given a list of rules,
 7  // returns a new list where the rules are chained togheter,
 8  // which means that they can be interpreted as a chain
 9  // of "if elsif elsif".
10  // The result is basically a list of rules where each filter
11  // is modified by adding an AND with the negation of all the
12  // previous filters.
13  chainFilters(fs)::
14    // utility that given a rule it returns its negated filter.
15    local negate(r) = { not: r.filter };
16    // recursive that goes trough all elements of arr
17    local aux(arr, i, negated, running) =
18      if i >= std.length(arr) then
19        running
20      else
21        // the new rule is an AND of:
22        // - the negation of all the previous rules
23        // - the current rule
24        local newr = {
25          filter: {
26            and: negated + [arr[i].filter],
27          },
28          actions: arr[i].actions,
29        };
30        aux(arr, i + 1, negated + [negate(arr[i])], running + [newr]) tailstrict;
31
32    if std.length(fs) == 0 then []
33    else aux(fs, 1, [negate(fs[0])], [fs[0]]),
34
35  // directlyTo matches only email where the recipient is in the 'TO'
36  // field, not the 'CC' or 'BCC' ones.
37  directlyTo(recipient):: {
38    and: [
39      { to: recipient },
40      { not: { cc: recipient } },
41      { not: { bcc: recipient } },
42    ],
43  },
44
45  local extendWithParents(labels) =
46    local extend(p) =
47      local comps = std.split(p, '/');
48      local aux(curr, rem) =
49        if std.length(rem) == 0 then
50          [curr]
51        else
52          aux(curr + '/' + rem[0], rem[1:]) + [curr];
53      if std.length(comps) == 1 then [p]
54      else aux(comps[0], comps[1:]);
55    std.flattenArrays([extend(l) for l in labels]),
56
57  // ruleLabels returns all the labels needed by the rule.
58  local ruleLabels(rule) =
59    if std.objectHas(rule.actions, 'labels') then
60      extendWithParents(rule.actions.labels)
61    else
62      [],
63
64  // ruleLabels returns all the labels needed by the given rules.
65  //
66  // Note that no other properties, other than the name, are attached
67  // to the labels (i.e. the color).
68  rulesLabels(rules)::
69    local labels = std.uniq(std.sort(std.flattenArrays([ruleLabels(x) for x in rules])));
70    [{ name: x } for x in labels],
71}