diff --git a/flake.nix b/flake.nix index 1b37178..bf2405b 100644 --- a/flake.nix +++ b/flake.nix @@ -18,6 +18,5 @@ type = "app"; program = toString runTests; }; - }); } diff --git a/lib.nix b/lib.nix index 9058db1..ae7db62 100644 --- a/lib.nix +++ b/lib.nix @@ -1,19 +1,46 @@ let - inherit (builtins) isString isFloat isInt isBool isList concatStringsSep; + inherit (builtins) isString isFloat isInt isBool isList isAttrs isNull; + inherit (builtins) concatStringsSep filter mapAttrs attrValues; + + mkLuaNil = { _type = "nil"; }; + isLuaNil = val: isAttrs val && val ? _type && val._type == "nil"; toLua = val: - if isList val then toLuaList val + if isLuaNil val then "nil" + else if isAttrs val then toLuaDict val + else if isList val then toLuaList val else if isString val then toLuaStr val else if isFloat val || isInt val then toString val else if isBool val then toLuaBool val - else ""; + else if isNull val then null + else null; - toLuaList = val: "{ ${concatStringsSep ", " (map toLua val)} }"; + toLuaList = val: + wrapObj (excludeNull (map toLua val)); - toLuaStr = val: "'${val}'"; + toLuaDict = val: + let + toDictItem = name: value: + let luaValue = toLua value; + in + if isNull luaValue then null + else "[${toLuaStr name}] = ${luaValue}"; + + dictItems = excludeNull (attrValues (mapAttrs toDictItem val)); + in + wrapObj dictItems; + + excludeNull = val: filter (v: !(isNull v)) val; + + wrapObj = val: "{ ${concatStringsSep ", " val} }"; + + toLuaStr = val: "\"${val}\""; toLuaBool = val: if val then "true" else "false"; + + in { inherit toLua; + inherit mkLuaNil; } diff --git a/lib.test.nix b/lib.test.nix index 28d31eb..eb28900 100644 --- a/lib.test.nix +++ b/lib.test.nix @@ -2,21 +2,29 @@ let nix2lua = import ./lib.nix; - inherit (nix2lua) toLua; + inherit (nix2lua) toLua mkLuaNil; in pkgs.lib.runTests { - "test returns an empty string" = { + "test returns null" = { expr = toLua null; - expected = ""; + expected = null; + }; + "test returns nil" = { + expr = toLua mkLuaNil; + expected = "nil"; }; "test returns a lua string" = { expr = toLua "hello world"; - expected = "'hello world'"; + expected = "\"hello world\""; }; "test returns an integer number" = { expr = toLua 10; expected = "10"; }; + "test returns a negative integer number" = { + expr = toLua (-10); + expected = "-10"; + }; "test returns a float number" = { expr = toLua 10.1; expected = "10.100000"; @@ -31,6 +39,34 @@ pkgs.lib.runTests { }; "test returns array with all primitive types" = { expr = toLua [ "hello" 10 10.1 true ]; - expected = "{ 'hello', 10, 10.100000, true }"; + expected = "{ \"hello\", 10, 10.100000, true }"; + }; + "test returns array without null values" = { + expr = toLua [ null "hello" null 10 null 10.1 null true null ]; + expected = "{ \"hello\", 10, 10.100000, true }"; + }; + "test returns dict" = { + expr = toLua { + foo = "hello"; + int = 10; + float = 10.1; + success = true; + fail = false; + }; + expected = "{ [\"fail\"] = false, [\"float\"] = 10.100000, [\"foo\"] = \"hello\", [\"int\"] = 10, [\"success\"] = true }"; + }; + "test returns dict without nullable items" = { + expr = toLua { foo = "hello"; bar = null; }; + expected = "{ [\"foo\"] = \"hello\" }"; + }; + "test returns recursive dict" = { + expr = toLua { + first = { + second = { + last = "hello"; + }; + }; + }; + expected = "{ [\"first\"] = { [\"second\"] = { [\"last\"] = \"hello\" } } }"; }; }