brand new ugly (but correct) kdl structure

This commit is contained in:
Josh Robson Chase 2024-04-15 07:55:03 -04:00
parent 1c43dcfac4
commit 110530ceab
3 changed files with 167 additions and 103 deletions

View file

@ -1,11 +1,22 @@
{ lib }: { lib }:
{ {
toKDL = { }: toKDL = { }:
let let
inherit (lib) concatStringsSep splitString mapAttrsToList any; inherit (lib) concatStringsSep;
inherit (builtins) typeOf replaceStrings elem; inherit (builtins) typeOf replaceStrings elem;
# KDL Spec Summary
# Document -> Node[]
# Node -> {[Type] NodeName [Args] [Properties] [Children]}
# Type -> Ident
# NodeName -> Ident
# Args -> Value[] # Note: ordered
# Properties -> map[Ident]Value # Note: Unordered
# Children -> Node[] # Note: ordered
# Value -> String | Number | Bool | Null
# ListOf String -> String # ListOf String -> String
indentStrings = let indentStrings = let
# Although the input of this function is a list of strings, # Although the input of this function is a list of strings,
@ -35,69 +46,49 @@
else else
toString element); toString element);
# Attrset Conversion # Node Attrset Conversion
# String -> AttrsOf Anything -> String # AttrsOf Anything -> String
convertAttrsToKDL = name: attrs: attrsToKDLNode = attrs:
let let
optArgsString = lib.optionalString (attrs ? "_args") optType = lib.optionalString (attrs ? "type") attrs.type;
(lib.pipe attrs._args [
name = attrs.name;
optArgsString = lib.optionalString (attrs ? "args")
(lib.pipe attrs.args [
(a: if typeOf a == "list" then a else [ a ])
(map literalValueToString) (map literalValueToString)
(lib.concatStringsSep " ") (lib.concatStringsSep " ")
(s: s + " ")
]); ]);
optPropsString = lib.optionalString (attrs ? "_props") optPropsString = lib.optionalString (attrs ? "props")
(lib.pipe attrs._props [ (lib.pipe attrs.props [
(lib.mapAttrsToList (lib.mapAttrsToList
(name: value: "${name}=${literalValueToString value}")) (name: value: "${name}=${literalValueToString value}"))
(lib.concatStringsSep " ") (lib.concatStringsSep " ")
(s: s + " ")
]); ]);
children = optChildren = lib.optionalString (attrs ? "children")
lib.filterAttrs (name: _: !(elem name [ "_args" "_props" ])) attrs; (lib.pipe attrs.children [
in '' (a: if typeOf a == "list" then a else [ a ])
${name} ${optArgsString}${optPropsString}{ (map attrsToKDLNode)
${indentStrings (mapAttrsToList convertAttributeToKDL children)} (s:
}''; lib.optionalString (builtins.length s > 0) ''
{
${indentStrings s}
}'')
]);
# List Conversion in lib.concatStringsSep " " (lib.filter (s: s != "") [
# String -> ListOf (OneOf [Int Float String Bool Null]) -> String optType
convertListOfFlatAttrsToKDL = name: list: name
let flatElements = map literalValueToString list; optArgsString
in "${name} ${concatStringsSep " " flatElements}"; optPropsString
optChildren
]);
# String -> ListOf Anything -> String in nodes: ''
convertListOfNonFlatAttrsToKDL = name: list: '' ${concatStringsSep "\n" (map attrsToKDLNode nodes)}
${name} {
${indentStrings (map (x: convertAttributeToKDL "-" x) list)}
}'';
# String -> ListOf Anything -> String
convertListToKDL = name: list:
let elementsAreFlat = !any (el: elem (typeOf el) [ "list" "set" ]) list;
in if elementsAreFlat then
convertListOfFlatAttrsToKDL name list
else
convertListOfNonFlatAttrsToKDL name list;
# Combined Conversion
# String -> Anything -> String
convertAttributeToKDL = name: value:
let vType = typeOf value;
in if elem vType [ "int" "float" "bool" "null" "string" ] then
"${name} ${literalValueToString value}"
else if vType == "set" then
convertAttrsToKDL name value
else if vType == "list" then
convertListToKDL name value
else
throw ''
Cannot convert type `(${typeOf value})` to KDL:
${name} = ${toString value}
'';
in attrs: ''
${concatStringsSep "\n" (mapAttrsToList convertAttributeToKDL attrs)}
''; '';
toSCFG = { }: toSCFG = { }:

View file

@ -1,14 +1,19 @@
a 1 a 1
b "string" b "string"
bigFlatItems 23847590283751 1.239000 "multiline \" \" \"\nstring\n" null
c "multiline string\nwith special characters:\n\t \n \\" \"\n" c "multiline string\nwith special characters:\n\t \n \\" \"\n"
unsafeString " \" \n "
flatItems 1 2 "asdf" true null
bigFlatItems 23847590283751 1.239000 "multiline \" \" \"\nstring\n" null
repeated 1 2
repeated true false
repeated
repeated null
extraAttrs 2 true arg1=1 arg2=false { extraAttrs 2 true arg1=1 arg2=false {
nested { nested {
a 1 a 1
b null b null
} }
} }
flatItems 1 2 "asdf" true null
listInAttrsInList { listInAttrsInList {
list1 { list1 {
- { - {
@ -27,15 +32,6 @@ listInAttrsInList {
} }
} }
list2 { list2 {
- {
a 8 a 8
} }
} }
}
nested {
- 1 2
- true false
-
- null
}
unsafeString " \" \n "

View file

@ -1,17 +1,32 @@
{ config, lib, ... }: { lib, ... }: {
home.file."tokdl-result.txt".text = lib.hm.generators.toKDL { } [
{ {
home.file."tokdl-result.txt".text = lib.hm.generators.toKDL { } { name = "a";
a = 1; args = 1;
b = "string"; }
c = '' {
name = "b";
args = "string";
}
{
name = "c";
args = ''
multiline string multiline string
with special characters: with special characters:
\t \n \" " \t \n \" "
''; '';
unsafeString = " \" \n "; }
flatItems = [ 1 2 "asdf" true null ]; {
bigFlatItems = [ name = "unsafeString";
args = " \" \n ";
}
{
name = "flatItems";
args = [ 1 2 "asdf" true null ];
}
{
name = "bigFlatItems";
args = [
23847590283751 23847590283751
1.239 1.239
'' ''
@ -20,30 +35,92 @@
'' ''
null null
]; ];
nested = [ [ 1 2 ] [ true false ] [ ] [ null ] ]; }
extraAttrs = { {
_args = [ 2 true ]; name = "repeated";
_props = { args = [ 1 2 ];
}
{
name = "repeated";
args = [ true false ];
}
{ name = "repeated"; }
{
name = "repeated";
args = [ null ];
}
{
name = "extraAttrs";
args = [ 2 true ];
props = {
arg1 = 1; arg1 = 1;
arg2 = false; arg2 = false;
}; };
nested = { children = {
a = 1; name = "nested";
b = null; children = [
};
};
listInAttrsInList = {
list1 = [
{ a = 1; }
{ b = true; }
{ {
c = null; name = "a";
d = [{ e = "asdfadfasdfasdf"; }]; args = [ 1 ];
}
{
name = "b";
args = [ null ];
} }
]; ];
list2 = [{ a = 8; }]; };
}
{
name = "listInAttrsInList";
children = [
{
name = "list1";
children = [
{
name = "-";
children = {
name = "a";
args = [ 1 ];
};
}
{
name = "-";
children = {
name = "b";
args = [ true ];
};
}
{
name = "-";
children = [
{
name = "c";
args = [ null ];
}
{
name = "d";
children = {
name = "-";
children = {
name = "e";
args = [ "asdfadfasdfasdf" ];
}; };
}; };
}
];
}
];
}
{
name = "list2";
children = [{
name = "a";
args = [ 8 ];
}];
}
];
}
];
nmt.script = '' nmt.script = ''
assertFileContent \ assertFileContent \