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 }:
{
toKDL = { }:
let
inherit (lib) concatStringsSep splitString mapAttrsToList any;
inherit (lib) concatStringsSep;
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
indentStrings = let
# Although the input of this function is a list of strings,
@ -35,69 +46,49 @@
else
toString element);
# Attrset Conversion
# String -> AttrsOf Anything -> String
convertAttrsToKDL = name: attrs:
# Node Attrset Conversion
# AttrsOf Anything -> String
attrsToKDLNode = attrs:
let
optArgsString = lib.optionalString (attrs ? "_args")
(lib.pipe attrs._args [
optType = lib.optionalString (attrs ? "type") attrs.type;
name = attrs.name;
optArgsString = lib.optionalString (attrs ? "args")
(lib.pipe attrs.args [
(a: if typeOf a == "list" then a else [ a ])
(map literalValueToString)
(lib.concatStringsSep " ")
(s: s + " ")
]);
optPropsString = lib.optionalString (attrs ? "_props")
(lib.pipe attrs._props [
optPropsString = lib.optionalString (attrs ? "props")
(lib.pipe attrs.props [
(lib.mapAttrsToList
(name: value: "${name}=${literalValueToString value}"))
(lib.concatStringsSep " ")
(s: s + " ")
]);
children =
lib.filterAttrs (name: _: !(elem name [ "_args" "_props" ])) attrs;
in ''
${name} ${optArgsString}${optPropsString}{
${indentStrings (mapAttrsToList convertAttributeToKDL children)}
}'';
optChildren = lib.optionalString (attrs ? "children")
(lib.pipe attrs.children [
(a: if typeOf a == "list" then a else [ a ])
(map attrsToKDLNode)
(s:
lib.optionalString (builtins.length s > 0) ''
{
${indentStrings s}
}'')
]);
# List Conversion
# String -> ListOf (OneOf [Int Float String Bool Null]) -> String
convertListOfFlatAttrsToKDL = name: list:
let flatElements = map literalValueToString list;
in "${name} ${concatStringsSep " " flatElements}";
in lib.concatStringsSep " " (lib.filter (s: s != "") [
optType
name
optArgsString
optPropsString
optChildren
]);
# String -> ListOf Anything -> String
convertListOfNonFlatAttrsToKDL = name: list: ''
${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)}
in nodes: ''
${concatStringsSep "\n" (map attrsToKDLNode nodes)}
'';
toSCFG = { }:

View file

@ -1,14 +1,19 @@
a 1
b "string"
bigFlatItems 23847590283751 1.239000 "multiline \" \" \"\nstring\n" null
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 {
nested {
a 1
b null
}
}
flatItems 1 2 "asdf" true null
listInAttrsInList {
list1 {
- {
@ -27,15 +32,6 @@ listInAttrsInList {
}
}
list2 {
- {
a 8
}
}
}
nested {
- 1 2
- true false
-
- null
}
unsafeString " \" \n "

View file

@ -1,17 +1,32 @@
{ config, lib, ... }:
{
home.file."tokdl-result.txt".text = lib.hm.generators.toKDL { } {
a = 1;
b = "string";
c = ''
{ lib, ... }: {
home.file."tokdl-result.txt".text = lib.hm.generators.toKDL { } [
{
name = "a";
args = 1;
}
{
name = "b";
args = "string";
}
{
name = "c";
args = ''
multiline string
with special characters:
\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
1.239
''
@ -20,30 +35,92 @@
''
null
];
nested = [ [ 1 2 ] [ true false ] [ ] [ null ] ];
extraAttrs = {
_args = [ 2 true ];
_props = {
}
{
name = "repeated";
args = [ 1 2 ];
}
{
name = "repeated";
args = [ true false ];
}
{ name = "repeated"; }
{
name = "repeated";
args = [ null ];
}
{
name = "extraAttrs";
args = [ 2 true ];
props = {
arg1 = 1;
arg2 = false;
};
nested = {
a = 1;
b = null;
};
};
listInAttrsInList = {
list1 = [
{ a = 1; }
{ b = true; }
children = {
name = "nested";
children = [
{
c = null;
d = [{ e = "asdfadfasdfasdf"; }];
name = "a";
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 = ''
assertFileContent \