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}