{ lib, pkgs, extraAttrs ? { }, }: with lib; let luaUtils = rec { # Primitives /** Converts a nix null into its Lua representation. Type: nullToLua :: Null -> "nil" */ nullToLua = nullValue: assert builtins.isNull nullValue; "nil"; /** Converts a nix boolean into its Lua representation. Type: boolToLua :: Bool -> String */ boolToLua = bool: assert builtins.isBool bool; if bool then "true" else "false"; /** Converts a nix string into its Lua representation. Type: stringToLua :: String -> String */ stringToLua = string: assert builtins.isString string; ''"${string}"''; /** Nix lambdas are called with luaUtils as an argument, the result will be used as a raw value. This function is used to insert unwrapped strings (like lua functions). Type: functionToLua :: lambda -> String */ functionToLua = lambda: assert builtins.isFunction lambda; lambda (extraAttrs // { inherit luaUtils; }); /** Converts a nix integer/float into its Lua representation. Type: numberToLua :: Int|Float -> String */ numberToLua = number: assert ((builtins.isInt number) || (builtins.isFloat number)); builtins.toJSON number; /** Converts a nix list into a Lua Table. The resulting Lua table will have its brackets removed if the first element of the list is "__unpack". Type: listToLua :: List -> String */ listToLua = list: assert builtins.isList list; if list != [ ] then let wrap = (lib.elemAt list 0) != "__unpack"; strippedList = if wrap then list else (lib.drop 1 list); in lib.concatStrings [ (optionalString wrap "{") (concatStringsSep "," (map toLua strippedList)) (optionalString wrap "}") ] else "{}"; /** Converts a nix set into its Lua representation. Derivations are converted to their string representation (outPath). Sets are converted into Lua tables. Sets take two special arguments: __unpack (Bool): Removes the brackets around the resulting Lua table. __posArgs (List): Positional arguments which precede the key value pairs. Type: setToLua :: Derivation|Set -> String */ setToLua = set: assert builtins.isAttrs set; if (lib.isDerivation set) then (stringToLua (builtins.toString set)) else if set != { } then let unpack = lib.optional (set ? __unpack) "__unpack"; posArgs = lib.optionals (set ? __posArgs) set.__posArgs; strippedSet = ( attrsets.removeAttrs set [ "__unpack" "__posArgs" ] ); keyArgs = (mapAttrsToList (key: val: (_: "${key} = ${toLua val}")) strippedSet); in listToLua (unpack ++ posArgs ++ keyArgs) else "{}"; /** A helper function to map nix data types to the correct function. Type: toLua :: Any -> String */ toLua = ( value: let # can be: null, bool, string, path, int, float, list, set or lambda type = builtins.typeOf value; in assert !(builtins.isFunction type) || builtins.throw "Nix functions (${type}) have no correspoinding Lua representation."; { "null" = nullToLua; "bool" = boolToLua; "string" = stringToLua; "lambda" = functionToLua; "path" = stringToLua; "int" = numberToLua; "float" = numberToLua; "list" = listToLua; "set" = setToLua; } ."${type}" value ); /** Writes a formatted Lua file containing ${text} to ${path}.lua Type: writeLuaFileDir :: Path -> String -> Derivation */ writeLuaFileDir = path: text: pkgs.writeTextFile rec { inherit text; destination = "/${path}.lua"; name = builtins.baseNameOf path; checkPhase = '' ${pkgs.stylua}/bin/stylua $out/${destination} ''; }; }; in luaUtils