summaryrefslogtreecommitdiffstats
path: root/lib/lua.nix
blob: 047871d6b1200f915fb1aa636214c087bf862856 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Helpers for converting values to lua
{lib}: let
  /**
  Test whether an object is a `luaInline` value (i.e. has `_type == "lua-inline"`).

  # Type

  ```
  isLuaInline :: Any -> Bool
  ```

  # Arguments

  - `object`: Any Nix value.

  # Example

  ```nix
  isLuaInline (lib.mkLuaInline "vim.fn.getcwd()")
  => true

  isLuaInline "just a string"
  => false
  ```
  */
  isLuaInline = object: (object._type or null) == "lua-inline";

  /**
  Recursively convert a Nix value to its Lua representation as a string.

  Handles all primitive Nix types as well as lists, attribute sets,
  derivations (rendered as their store path string), and `luaInline` values
  (rendered verbatim). Null attributes are stripped from sets.

  # Type

  ```
  toLuaObject :: Any -> String
  ```

  # Arguments

  - `args`: Any Nix value to convert.

  # Example

  ```nix
  toLuaObject { a = 1; b = true; c = null; }
  => ''{["a"] = 1,\n["b"] = true}''

  toLuaObject [ "x" "y" ]
  => ''{"x",\n"y"}''
  ```
  */
  toLuaObject = args:
    {
      int = toString args;
      float = toString args;

      # escapes \ and quotes
      string = builtins.toJSON args;
      path = builtins.toJSON args;

      bool = lib.boolToString args;
      null = "nil";

      list = "{${lib.concatMapStringsSep ",\n" toLuaObject args}}";

      set =
        if lib.isDerivation args
        then ''"${args}"''
        else if isLuaInline args
        then args.expr
        else "{${
          lib.pipe args [
            (lib.filterAttrs (_: v: v != null))
            (builtins.mapAttrs (
              n: v:
                if lib.hasPrefix "@" n
                then toLuaObject v
                else "[${toLuaObject n}] = ${toLuaObject v}"
            ))
            builtins.attrValues
            (lib.concatStringsSep ",\n")
          ]
        }}";
    }
    .${
      builtins.typeOf args
    }
    or (builtins.throw "Could not convert object of type `${builtins.typeOf args}` to lua object");
in {
  inherit isLuaInline toLuaObject;

  /**
  Convert a list of Lua expression strings into a Lua table string.

  Each element is wrapped with `mkLuaInline` before conversion so that
  strings are treated as raw Lua rather than quoted string literals.

  # Type

  ```
  luaTable :: [String] -> String
  ```

  # Arguments

  - `x`: List of Lua expression strings.

  # Example

  ```nix
  luaTable [ "vim.fn.getcwd()" "vim.fn.expand('%')" ]
  => ''{vim.fn.getcwd(),\nvim.fn.expand('%')}''
  ```
  */
  luaTable = x: (toLuaObject (map lib.mkLuaInline x));
}