From 7287c0e076c3fd69d55e96cdc5c46e951bed01d4 Mon Sep 17 00:00:00 2001 From: Mykola Orliuk Date: Sat, 29 Apr 2023 18:35:07 +0200 Subject: [PATCH] lib.generators.toLua: asBindings option Allows to generate code block for setting of global variables --- lib/generators.nix | 24 +++++++++++++++++++++--- lib/tests/misc.nix | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/lib/generators.nix b/lib/generators.nix index 4ecbdac3c125..c46ecca58c68 100644 --- a/lib/generators.nix +++ b/lib/generators.nix @@ -434,6 +434,7 @@ ${expr "" v} Configuration: * multiline - by default is true which results in indented block-like view. * indent - initial indent. + * asBindings - by default generate single value, but with this use attrset to set global vars. Attention: Regardless of multiline parameter there is no trailing newline. @@ -464,18 +465,35 @@ ${expr "" v} /* If this option is true, the output is indented with newlines for attribute sets and lists */ multiline ? true, /* Initial indentation level */ - indent ? "" + indent ? "", + /* Interpret as variable bindings */ + asBindings ? false, }@args: v: with builtins; let innerIndent = "${indent} "; introSpace = if multiline then "\n${innerIndent}" else " "; outroSpace = if multiline then "\n${indent}" else " "; - innerArgs = args // { indent = innerIndent; }; + innerArgs = args // { + indent = if asBindings then indent else innerIndent; + asBindings = false; + }; concatItems = concatStringsSep ",${introSpace}"; isLuaInline = { _type ? null, ... }: _type == "lua-inline"; + + generatedBindings = + assert lib.assertMsg (badVarNames == []) "Bad Lua var names: ${toPretty {} badVarNames}"; + libStr.concatStrings ( + lib.attrsets.mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v + ); + + # https://en.wikibooks.org/wiki/Lua_Programming/variable#Variable_names + matchVarName = match "[[:alpha:]_][[:alnum:]_]*(\\.[[:alpha:]_][[:alnum:]_]*)*"; + badVarNames = filter (name: matchVarName name == null) (attrNames v); in - if v == null then + if asBindings then + generatedBindings + else if v == null then "nil" else if isInt v || isFloat v || isString v || isBool v then builtins.toJSON v diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 49336b8b9630..ea3548b9514e 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -4,6 +4,11 @@ with import ../default.nix; let + testingThrow = expr: { + expr = (builtins.tryEval (builtins.seq expr "didn't throw")); + expected = { success = false; value = false; }; + }; + testingDeepThrow = expr: testingThrow (builtins.deepSeq expr expr); testSanitizeDerivationName = { name, expected }: let @@ -962,6 +967,41 @@ runTests { expected = ''{ 41, 43 }''; }; + testToLuaEmptyBindings = { + expr = generators.toLua { asBindings = true; } {}; + expected = ""; + }; + + testToLuaBindings = { + expr = generators.toLua { asBindings = true; } { x1 = 41; _y = { a = 43; }; }; + expected = '' + _y = { + ["a"] = 43 + } + x1 = 41 + ''; + }; + + testToLuaPartialTableBindings = { + expr = generators.toLua { asBindings = true; } { "x.y" = 42; }; + expected = '' + x.y = 42 + ''; + }; + + testToLuaIndentedBindings = { + expr = generators.toLua { asBindings = true; indent = " "; } { x = { y = 42; }; }; + expected = " x = {\n [\"y\"] = 42\n }\n"; + }; + + testToLuaBindingsWithSpace = testingThrow ( + generators.toLua { asBindings = true; } { "with space" = 42; } + ); + + testToLuaBindingsWithLeadingDigit = testingThrow ( + generators.toLua { asBindings = true; } { "11eleven" = 42; } + ); + testToLuaBasicExample = { expr = generators.toLua {} { cmd = [ "typescript-language-server" "--stdio" ];