@@ -56,7 +56,16 @@ rec {
5656 };
5757 };
5858
59− ini = { listsAsDuplicateKeys ? false, ... }@args: {
59+ ini = {
60+ # Represents lists as duplicate keys
61+ listsAsDuplicateKeys ? false,
62+ # Alternative to listsAsDuplicateKeys, converts list to non-list
63+ # listToValue :: [IniAtom] -> IniAtom
64+ listToValue ? null,
65+ ...
66+ }@args:
67+ assert !listsAsDuplicateKeys || listToValue == null;
68+ {
6069
6170 type = with lib.types; let
6271
@@ -74,12 +83,25 @@ rec {
7483 coercedTo singleIniAtom lib.singleton (listOf singleIniAtom) // {
7584 description = singleIniAtom.description + " or a list of them for duplicate keys";
7685 }
86+ else if listToValue != null then
87+ coercedTo singleIniAtom lib.singleton (nonEmptyListOf singleIniAtom) // {
88+ description = singleIniAtom.description + " or a non-empty list of them";
89+ }
7790 else
7891 singleIniAtom;
7992
8093 in attrsOf (attrsOf iniAtom);
8194
82− generate = name: value: pkgs.writeText name (lib.generators.toINI args value);
95+ generate = name: value:
96+ let
97+ transformedValue =
98+ if listToValue != null
99+ then
100+ lib.mapAttrs (section: lib.mapAttrs (key: val:
101+ if lib.isList val then listToValue val else val
102+ )) value
103+ else value;
104+ in pkgs.writeText name (lib.generators.toINI (removeAttrs args ["listToValue"]) transformedValue);
83105
84106 };
85107