1lib :
2
3with lib;
4
5rec {
6 paramsToConf = cfg : ps : mkConf 0 (paramsToRenderedStrings cfg ps);
7
8 # mkConf takes an indentation level (which usually starts at 0) and a nested
9 # attribute set of strings and will render that set to a strongswan.conf style
10 # configuration format. For example:
11 #
12 # mkConf 0 {a = "1"; b = { c = { "foo" = "2"; "bar" = "3"; }; d = "4";};} => ''
13 # a = 1
14 # b {
15 # c {
16 # foo = 2
17 # bar = 3
18 # }
19 # d = 4
20 # }''
21 mkConf = indent : ps :
22 concatMapStringsSep "\n"
23 (name:
24 let value = ps.${name};
25 indentation = replicate indent " ";
26 in
27 indentation + (
28 if isAttrs value
29 then "${name} {\n" +
30 mkConf (indent + 2) value + "\n" +
31 indentation + "}"
32 else "${name} = ${value}"
33 )
34 )
35 (attrNames ps);
36
37 replicate = n : c : concatStrings (builtins.genList (_x : c) n);
38
39 # `paramsToRenderedStrings cfg ps` converts the NixOS configuration `cfg`
40 # (typically the "config" argument of a NixOS module) and the set of
41 # parameters `ps` (an attribute set where the values are constructed using the
42 # parameter constructors in ./param-constructors.nix) to a nested attribute
43 # set of strings (rendered parameters).
44 paramsToRenderedStrings = cfg : ps :
45 filterEmptySets (
46 (mapParamsRecursive (path: name: param:
47 let value = attrByPath path null cfg;
48 in optionalAttrs (value != null) (param.render name value)
49 ) ps));
50
51 filterEmptySets = set : filterAttrs (n: v: (v != null)) (mapAttrs (name: value:
52 if isAttrs value
53 then let value' = filterEmptySets value;
54 in if value' == {}
55 then null
56 else value'
57 else value
58 ) set);
59
60 # Recursively map over every parameter in the given attribute set.
61 mapParamsRecursive = mapAttrsRecursiveCond' (as: (!(as ? _type && as._type == "param")));
62
63 mapAttrsRecursiveCond' = cond: f: set:
64 let
65 recurse = path: set:
66 let
67 g =
68 name: value:
69 if isAttrs value && cond value
70 then { ${name} = recurse (path ++ [name]) value; }
71 else f (path ++ [name]) name value;
72 in mapAttrs'' g set;
73 in recurse [] set;
74
75 mapAttrs'' = f: set:
76 foldl' (a: b: a // b) {} (map (attr: f attr set.${attr}) (attrNames set));
77
78 # Extract the options from the given set of parameters.
79 paramsToOptions = ps :
80 mapParamsRecursive (_path: name: param: { ${name} = param.option; }) ps;
81
82}