mirror of
https://github.com/nix-community/home-manager
synced 2024-11-30 15:09:46 +01:00
brand new ugly (but correct) kdl structure
This commit is contained in:
parent
1c43dcfac4
commit
110530ceab
3 changed files with 167 additions and 103 deletions
|
@ -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 = { }:
|
||||
|
|
|
@ -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 "
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in a new issue