From 43d0794bcd4c4f3ee7d0e4831b07813324dae9b5 Mon Sep 17 00:00:00 2001 From: cjshearer Date: Sun, 24 Nov 2024 20:03:10 -0500 Subject: [PATCH] lib: init toRON --- modules/lib/generators.nix | 50 +++++++++++++++++ tests/lib/generators/default.nix | 1 + tests/lib/generators/toron-result.txt | 71 ++++++++++++++++++++++++ tests/lib/generators/toron.nix | 77 +++++++++++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 tests/lib/generators/toron-result.txt create mode 100644 tests/lib/generators/toron.nix diff --git a/modules/lib/generators.nix b/modules/lib/generators.nix index 2aebd92c99c7..76f75ed8a58d 100644 --- a/modules/lib/generators.nix +++ b/modules/lib/generators.nix @@ -143,6 +143,56 @@ ${concatStringsSep "\n" (mapAttrsToList convertAttributeToKDL attrs)} ''; + # https://github.com/ron-rs/ron/blob/master/docs/grammar.md + toRON = { }: + let + inherit (lib) + filterAttrs concatStrings concatStringsSep mapAttrsToList boolToString; + inherit (builtins) typeOf toString; + + serialize = indentLevel: value: + let + indent = lib.strings.replicate indentLevel " "; + indentNested = indent + " "; + serializeNested = v: serialize (indentLevel + 1) v; + serializationRules = { + int = toString; + float = toString; + bool = boolToString; + string = s: ''"${toString s}"''; + path = toString; + null = toString; + set = hashMap: + lib.pipe hashMap [ + (filterAttrs (k: v: v != null)) + (mapAttrsToList + (k: v: "${indentNested}${k}: ${serializeNested v}")) + (concatStringsSep ("," + "\n")) + (hashMap: "{" + "\n" + hashMap + "\n" + indent + "}") + ]; + list = list: + lib.pipe list [ + (map (v: "${indentNested}${serializeNested v}")) + (concatStringsSep ("," + "\n")) + (list: "[" + "\n" + list + "\n" + indent + "]") + ]; + lambda = lambda: + let + ident = ({ident = "";} // (builtins.functionArgs lambda)).ident; + lambdaResult = lambda { }; + in (serializationRules // { + string = toString; + list = tuple: + lib.pipe tuple [ + (map (v: "${indentNested}${serializeNested v}")) + (concatStringsSep ("," + "\n")) + (tuple: ident + "(" + "\n" + tuple + "\n" + indent + ")") + ]; + }).${typeOf lambdaResult} lambdaResult; + }; + in serializationRules.${typeOf value} value; + in serialize 0; + toSCFG = { }: let inherit (lib) concatStringsSep mapAttrsToList any; diff --git a/tests/lib/generators/default.nix b/tests/lib/generators/default.nix index da52640d1298..7cfe9a24c3c0 100644 --- a/tests/lib/generators/default.nix +++ b/tests/lib/generators/default.nix @@ -1,5 +1,6 @@ { generators-tokdl = ./tokdl.nix; + generators-toron = ./toron.nix; generators-toscfg-empty = ./toscfg-empty.nix; generators-toscfg-example = ./toscfg-example.nix; } diff --git a/tests/lib/generators/toron-result.txt b/tests/lib/generators/toron-result.txt new file mode 100644 index 000000000000..c1037ce8ba49 --- /dev/null +++ b/tests/lib/generators/toron-result.txt @@ -0,0 +1,71 @@ +[ + { + byte: b'0', + float_exp: -1.0e-16, + float_frac: .1, + float_int: 1000, + float_std: 1000.000000, + float_suffix: -.1f64, + integer: 0, + integer_suffix: i8, + unsigned_binary: 0b10, + unsigned_decimal: 10, + unsigned_hexadecimal: 0x10, + unsigned_octal: 0o10 + }, + { + byte_string_raw: br##"Hello, World!"##, + byte_string_std: b"Hello, World!", + string_escape_ascii: "\'", + string_escape_byte: "\x0A", + string_escape_unicode: "\u{0A0A}", + string_raw: r##"This is a "raw string". +It can contain quotations or backslashes (\)!"##, + string_std: "Hello, World!" + }, + { + char: 'a' + }, + { + boolean: true + }, + { + option_none: None, + option_some: Some(10) + }, + { + list: [ + 1, + 2, + 3 + ] + }, + { + map: { + a: 1, + b: 2, + c: 3 + } + }, + { + tuple: ( + 1, + 2, + 3 + ) + }, + { + tuple_struct: ( + 1, + 2, + 3 + ), + tuple_struct_ident: MyTupleStruct( + 1, + 2, + 3 + ), + unit_struct: (), + unit_struct_ident: MyUnitStruct + } +] \ No newline at end of file diff --git a/tests/lib/generators/toron.nix b/tests/lib/generators/toron.nix new file mode 100644 index 000000000000..d669fd2aa233 --- /dev/null +++ b/tests/lib/generators/toron.nix @@ -0,0 +1,77 @@ +{ config, lib, ... }: + +{ + home.file."toron-result.txt".text = lib.hm.generators.toRON { } [ + # numbers + { + byte = f: "b'0'"; + # while nix supports scientific notation, it will convert -1.0e-16 to -0.000000 + float_exp = f: "-1.0e-16"; + # while nix supports fractional notation, nix fmt will complain about .1 + float_frac = f: ".1"; + float_int = 1000; + float_std = 1000.0; + float_suffix = f: "-.1f64"; + integer = 0; + integer_suffix = f: "i8"; + unsigned_binary = f: "0b10"; + unsigned_decimal = 10; + unsigned_hexadecimal = f: "0x10"; + unsigned_octal = f: "0o10"; + } + # strings + { + byte_string_raw = f: ''br##"Hello, World!"##''; + byte_string_std = f: ''b"Hello, World!"''; + string_escape_ascii = "\\'"; + string_escape_byte = "\\x0A"; + string_escape_unicode = "\\u{0A0A}"; + string_raw = f: '' + r##"This is a "raw string". + It can contain quotations or backslashes (\)!"##''; + string_std = "Hello, World!"; + } + # char + { + char = f: "'a'"; + } + # boolean + { + boolean = true; + } + # option + { + option_none = f: "None"; + option_some = f: "Some(10)"; + } + # list + { + list = [ 1 2 3 ]; + } + # map + { + map = { + a = 1; + b = 2; + c = 3; + }; + } + # tuple + { + tuple = f: [ 1 2 3 ]; + } + # struct + { + tuple_struct = f: [ 1 2 3 ]; + tuple_struct_ident = f: [ 1 2 3 ]; + unit_struct = f: "()"; + unit_struct_ident = f: "MyUnitStruct"; + } + ]; + + nmt.script = '' + assertFileContent \ + home-files/toron-result.txt \ + ${./toron-result.txt} + ''; +}