Profpatsch/third_party/overlays/sam/pkgs/lib/generators/preserves.nix
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
  Translate a literal Nix expression to Preserves text syntax.

  # Inputs

  Options
  : ignoreNulls
  : Whether null values in attrsets are dropped.
  : rawStrings
  : Whether Nix string values should be JSON-quoted or left as-is.

  Value
  : The literal value to convert to Preserves text.
*/
{ lib }:
{ ignoreNulls ? true
, rawStrings ? false
}:
let
  toPreserves =
    let
      inherit (lib) isDerivation;
      concatItems = toString;
      mapToSeq = v: toString (map toPreserves v);
      recordLabel =
        list:
          with builtins;
          let
            len = length list;
          in
          if len == 0 then
            null
          else
            let
              end = elemAt list (len - 1);
            in
            if (lib.isAttrs end) && (attrNames end) == [ "_record" ] then end._record else null;
      dictTuple = key: val: "${key}: ${toPreserves val}";
      attrToDict =
        if !ignoreNulls then dictTuple else key: val: if val != null then dictTuple key val else "";
      convert = {
        int = toString;
        bool = v: if v then "#t" else "#f";
        string = if rawStrings then lib.id else builtins.toJSON;
        path = v: toPreserves (toString v);
        null = _: "<null>";
        set =
          v:
          if v ? __toPreserves then
            v.__toPreserves (builtins.removeAttrs v [ "__toPreserves" ])
          else if (isDerivation v) then
            (builtins.toJSON v)
          else
            "{ ${concatItems (lib.attrsets.mapAttrsToList attrToDict v)} }";
        list =
          v:
          let
            label = recordLabel v;
          in
          if label == null then "[ ${mapToSeq v} ]" else "<${label} ${mapToSeq (lib.lists.init v)}>";
        lambda = abort "generators.toPreserves cannot convert lambdas";
        float = builtins.toJSON;
      };
    in
    v: convert.${builtins.typeOf v} v;
in
toPreserves