2022-11-18 02:36:55 +03:00
|
|
|
let
|
2022-11-18 12:40:18 +03:00
|
|
|
inherit (builtins) isString isFloat isInt isBool isList isAttrs isNull;
|
|
|
|
inherit (builtins) concatStringsSep filter mapAttrs attrValues;
|
|
|
|
|
2022-11-19 00:25:30 +03:00
|
|
|
mkLuaRaw = raw: { _type = "raw"; inherit raw; };
|
|
|
|
isLuaRaw = val: getType val == "raw";
|
|
|
|
|
2022-11-18 12:40:18 +03:00
|
|
|
mkLuaNil = { _type = "nil"; };
|
2022-11-18 22:46:17 +03:00
|
|
|
isLuaNil = val: getType val == "nil";
|
|
|
|
|
2022-11-19 03:43:29 +03:00
|
|
|
mkNamedField = name: value: {
|
|
|
|
_type = "table_field";
|
2022-11-18 22:46:17 +03:00
|
|
|
name = validString name;
|
|
|
|
value = toLua value;
|
|
|
|
};
|
2022-11-19 03:43:29 +03:00
|
|
|
isNamedField = val: getType val == "table_field";
|
|
|
|
toLuaNamedField = name: value:
|
2022-11-18 22:46:17 +03:00
|
|
|
if isNull value then null
|
|
|
|
else "[${toLuaStr name}] = ${value}";
|
2022-11-18 02:36:55 +03:00
|
|
|
|
2022-11-19 03:43:29 +03:00
|
|
|
toLua = val: toLuaInternal 0 val;
|
|
|
|
|
|
|
|
toLuaInternal = depth: val:
|
|
|
|
let nextDepth = depth + 1; in
|
2022-11-18 12:40:18 +03:00
|
|
|
if isLuaNil val then "nil"
|
2022-11-19 00:25:30 +03:00
|
|
|
else if isLuaRaw val then val.raw
|
2022-11-19 03:43:29 +03:00
|
|
|
else if isNamedField val then
|
|
|
|
if depth > 0 then toLuaNamedField val.name val.value
|
|
|
|
else error "You cannot render table field at the top level"
|
|
|
|
else if isAttrs val then toLuaTable nextDepth val
|
|
|
|
else if isList val then toLuaList nextDepth val
|
2022-11-18 02:36:55 +03:00
|
|
|
else if isString val then toLuaStr val
|
|
|
|
else if isFloat val || isInt val then toString val
|
|
|
|
else if isBool val then toLuaBool val
|
2022-11-18 12:40:18 +03:00
|
|
|
else if isNull val then null
|
2022-11-19 03:43:29 +03:00
|
|
|
else error "Value '${toString val}' is not supported";
|
2022-11-18 12:40:18 +03:00
|
|
|
|
2022-11-19 03:43:29 +03:00
|
|
|
toLuaList = depth: val:
|
|
|
|
wrapObj (excludeNull (map (toLuaInternal depth) val));
|
2022-11-18 12:40:18 +03:00
|
|
|
|
2022-11-19 03:43:29 +03:00
|
|
|
toLuaTable = depth: val: toLuaInternal depth (attrValues (mapAttrs mkNamedField val));
|
2022-11-18 02:36:55 +03:00
|
|
|
|
2022-11-18 12:40:18 +03:00
|
|
|
excludeNull = val: filter (v: !(isNull v)) val;
|
2022-11-18 02:36:55 +03:00
|
|
|
|
2022-11-18 12:40:18 +03:00
|
|
|
wrapObj = val: "{ ${concatStringsSep ", " val} }";
|
|
|
|
|
2022-11-18 22:46:17 +03:00
|
|
|
toLuaStr = val: "\"${validString val}\"";
|
2022-11-18 02:36:55 +03:00
|
|
|
|
|
|
|
toLuaBool = val: if val then "true" else "false";
|
2022-11-18 12:40:18 +03:00
|
|
|
|
2022-11-18 22:46:17 +03:00
|
|
|
getType = val: if isAttrs val && val ? _type then val._type else null;
|
|
|
|
|
|
|
|
validString = value:
|
|
|
|
if isString value then value
|
2022-11-19 03:43:29 +03:00
|
|
|
else error "Value '${toString value}' is not a valid string";
|
|
|
|
|
|
|
|
error = message: throw "[nix2lua] ${message}";
|
2022-11-18 02:36:55 +03:00
|
|
|
in
|
|
|
|
{
|
|
|
|
inherit toLua;
|
2022-11-19 03:43:29 +03:00
|
|
|
inherit mkLuaNil mkLuaRaw mkNamedField;
|
2022-11-18 02:36:55 +03:00
|
|
|
}
|