Initial commit
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
{
|
||||
lib,
|
||||
pkgs,
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
concatStringsSep
|
||||
splitString
|
||||
mapAttrsToList
|
||||
any
|
||||
optionalString
|
||||
pipe
|
||||
filterAttrs
|
||||
;
|
||||
inherit (builtins) typeOf replaceStrings elem;
|
||||
|
||||
indentStrings = let
|
||||
unlines = splitString "\n";
|
||||
lines = concatStringsSep "\n";
|
||||
indentAll = lines: concatStringsSep "\n" (map (x: " " + x) lines);
|
||||
in
|
||||
stringsWithNewlines: indentAll (unlines (lines stringsWithNewlines));
|
||||
|
||||
sanitizeString = replaceStrings ["\n" ''"'' "\\" "\r" "\t"] ["\\n" ''\"'' "\\\\" "\\r" "\\t"];
|
||||
|
||||
literalValueToString = element:
|
||||
lib.throwIfNot
|
||||
(elem (typeOf element) [
|
||||
"int"
|
||||
"float"
|
||||
"string"
|
||||
"bool"
|
||||
"null"
|
||||
])
|
||||
"Cannot convert value of type ${typeOf element} to KDL literal."
|
||||
(
|
||||
if typeOf element == "null"
|
||||
then "null"
|
||||
else if element == false
|
||||
then "false"
|
||||
else if element == true
|
||||
then "true"
|
||||
else if typeOf element == "string"
|
||||
then ''"${sanitizeString element}"''
|
||||
else toString element
|
||||
);
|
||||
|
||||
convertAttrsToKDL = name: attrs: let
|
||||
optArgsString = optionalString (attrs ? _args) (
|
||||
pipe attrs._args [
|
||||
(map literalValueToString)
|
||||
(concatStringsSep " ")
|
||||
(s: s + " ")
|
||||
]
|
||||
);
|
||||
optPropsString = optionalString (attrs ? _props) (
|
||||
pipe attrs._props [
|
||||
(mapAttrsToList (name: value: "${name}=${literalValueToString value}"))
|
||||
(concatStringsSep " ")
|
||||
(s: s + " ")
|
||||
]
|
||||
);
|
||||
children =
|
||||
filterAttrs (
|
||||
name: _:
|
||||
!(elem name [
|
||||
"_args"
|
||||
"_props"
|
||||
])
|
||||
)
|
||||
attrs;
|
||||
in
|
||||
''${name} ${optArgsString}${optPropsString}''
|
||||
+ (
|
||||
if children == {}
|
||||
then ""
|
||||
else "{\n${indentStrings (mapAttrsToList convertAttributeToKDL children)}\n}"
|
||||
);
|
||||
|
||||
convertListOfFlatAttrsToKDL = name: list: let
|
||||
flatElements = map literalValueToString list;
|
||||
in "${name} ${concatStringsSep " " flatElements}";
|
||||
|
||||
convertListOfNonFlatAttrsToKDL = name: list: ''${concatStringsSep "\n" (map (x: convertAttributeToKDL name x) list)}'';
|
||||
|
||||
convertListToKDL = name: list: let
|
||||
elementsAreFlat =
|
||||
!any (
|
||||
el:
|
||||
elem (typeOf el) [
|
||||
"list"
|
||||
"set"
|
||||
]
|
||||
)
|
||||
list;
|
||||
|
||||
allSingleValues =
|
||||
builtins.all (
|
||||
el:
|
||||
elem (typeOf el) ["int" "float" "string" "bool" "null"]
|
||||
)
|
||||
list;
|
||||
|
||||
isListOfLists = builtins.all (el: typeOf el == "list") list;
|
||||
in
|
||||
if isListOfLists
|
||||
then concatStringsSep "\n" (map (sublist: "${name} ${concatStringsSep " " (map literalValueToString sublist)}") list)
|
||||
else if elementsAreFlat && allSingleValues && builtins.length list > 1
|
||||
then concatStringsSep "\n" (map (val: "${name} ${literalValueToString val}") list)
|
||||
else if elementsAreFlat
|
||||
then convertListOfFlatAttrsToKDL name list
|
||||
else convertListOfNonFlatAttrsToKDL name list;
|
||||
|
||||
convertAttributeToKDL = name: value: let
|
||||
vType = typeOf value;
|
||||
in
|
||||
if
|
||||
elem vType [
|
||||
"int"
|
||||
"float"
|
||||
"bool"
|
||||
"string"
|
||||
]
|
||||
then "${name} ${literalValueToString value}"
|
||||
else if vType == "null"
|
||||
then "${name} ${literalValueToString value}"
|
||||
else if vType == "set"
|
||||
then
|
||||
if value == {}
|
||||
then name
|
||||
else convertAttrsToKDL name value
|
||||
else if vType == "list"
|
||||
then convertListToKDL name value
|
||||
else
|
||||
throw ''
|
||||
Cannot convert type `(${typeOf value})` to KDL:
|
||||
${name} = ${toString value}
|
||||
'';
|
||||
|
||||
toKDL = attrs: ''
|
||||
${concatStringsSep "\n" (mapAttrsToList convertAttributeToKDL attrs)}
|
||||
'';
|
||||
in {
|
||||
generate = name: value:
|
||||
pkgs.writeText name (toKDL value);
|
||||
}
|
||||
Reference in New Issue
Block a user