pkgs:
let
util = import ../. pkgs;
inherit (util.str) isEmp;
inherit (util.fn) notP;
inherit (builtins) isString match toJSON isList isAttrs all filter concatStringsSep;
inherit (pkgs.lib) mapAttrsToList concatMapStringsSep optionalString const;
partitionAttrs = util.attrset.partition;
tomlEscapeKey = val:
if isString val && match "[A-Za-z0-9_-]+" val != null
then val
else toJSON val;
tomlEscapeValue = toJSON;
tomlValue = v:
if isList v
then "[${concatMapStringsSep ", " tomlValue v}]"
else if isAttrs v
then "{${v |> mapAttrsToList tomlKV |> concatStringsSep ", "}}"
else tomlEscapeValue v;
tomlKV = k: v: "${tomlEscapeKey k} = ${tomlValue v}";
dots = concatMapStringsSep "." tomlEscapeKey;
tomlTable = oldPrefix: k: v:
let
prefix = oldPrefix ++ [k];
rest = imp prefix v;
in "[${dots prefix}]" + optionalString (rest != "") "\n${rest}";
tomlTableArray = oldPrefix: k: subtables:
let prefix = oldPrefix ++ [k];
in concatMapStringsSep "\n\n" (v:
let rest = imp prefix v;
in "[[${dots prefix}]]" + optionalString (rest != "") "\n${rest}") subtables;
imp = prefix: attrs:
let
byValue = const;
tableSplit = partitionAttrs (byValue isAttrs) attrs;
tablesToml = tableSplit.right
|> mapAttrsToList (tomlTable prefix)
|> concatStringsSep "\n\n";
tableArraySplit = partitionAttrs
(byValue (value: isList value && value != [] && all isAttrs value))
tableSplit.wrong;
tableArraysToml = tableArraySplit.right
|> mapAttrsToList (tomlTableArray prefix)
|> concatStringsSep "\n\n";
pairsToml = tableArraySplit.wrong |> mapAttrsToList tomlKV |> concatStringsSep "\n";
in filter (notP isEmp) [pairsToml tablesToml tableArraysToml] |> concatStringsSep "\n\n";
in imp []