about summary refs log tree commit diff
path: root/users/Profpatsch/toINI.nix
blob: 537505d30bbc4df2ee23d54718189689c1cf210a (plain) (blame)
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
68
69
70
71
72
73
74
75
76
77
78
79
{ lib, ... }:
let
  /* Generate an INI-style config file from an attrset
   * specifying the global section (no header), and a
   * list of sections which contain name/value pairs.
   *
   * generators.toINI {} {
   *   globalSection = [
   *     { name = "someGlobalKey"; value = "hi"; }
   *   ];
   *   sections = [
   *     { name = "foo"; value = [
   *         { name = "hi"; value = "${pkgs.hello}"; }
   *         { name = "ciao"; value = "bar"; }
   *       ];
   *     }
   *     { name = "baz";
   *       value = [ { name = "also, integers"; value = 42; } ];
   *     }
   *   ];
   * }
   *
   *> someGlobalKey=hi
   *>
   *> [foo]
   *> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
   *> ciao=bar
   *>
   *> [baz]
   *> also, integers=42
   *>
   *
   * The mk* configuration attributes can generically change
   * the way sections and key-value strings are generated.
   *
   * Order of the sections and of keys is preserved,
   * duplicate keys are allowed.
   */
  toINI =
    {
      # apply transformations (e.g. escapes) to section names
      mkSectionName ? (name: lib.strings.escape [ "[" "]" ] name)
    , # format a setting line from key and value
      mkKeyValue ? lib.generators.mkKeyValueDefault { } "="
    ,
    }: { globalSection, sections }:
    let
      mkSection = sectName: sectValues: ''
        [${mkSectionName sectName}]
      '' + toKeyValue { inherit mkKeyValue; } sectValues;
      # map input to ini sections
      mkSections = lib.strings.concatMapStringsSep "\n"
        ({ name, value }: mkSection name value)
        sections;
      mkGlobalSection =
        if globalSection == [ ]
        then ""
        else toKeyValue { inherit mkKeyValue; } globalSection
          + "\n";
    in
    mkGlobalSection
    + mkSections;

  /* Generate a name-value-style config file from a list.
   *
   * mkKeyValue is the same as in toINI.
   */
  toKeyValue =
    { mkKeyValue ? lib.generators.mkKeyValueDefault { } "="
    ,
    }:
    let
      mkLine = k: v: mkKeyValue k v + "\n";
      mkLines = k: v: [ (mkLine k v) ];
    in
    nameValues: lib.strings.concatStrings (lib.concatLists (map ({ name, value }: mkLines name value) nameValues));

in
toINI