# `WardrikLua.Sandbox`

Runs Lua code under limits, with no access to the node.

Built on [lua](https://hexdocs.pm/lua), a Lua 5.3 VM written in Elixir.

    WardrikLua.Sandbox.run("return ('%d apples'):format(3)", WardrikLua.Sandbox.Limits.new())
    #=> {:ok, "3 apples"}

Errors are returned as a sentence, since a model reads them.

## Globals

`string`, `table`, `math`, `utf8` and the safe parts of `os` are available. `io`, `file`,
`os.execute`, `os.exit`, `os.getenv`, `package`, `require`, `load`, `dofile`, `print` and `debug`
raise when called.

## Return values

  * No value returns `nil`, one value returns itself, several return a list.
  * A table returns a map, or a list when its keys are exactly `1..n`.
  * Map keys become strings. Keys that collide after conversion are an error.
  * Functions, cyclic tables and strings that aren't valid UTF-8 are an error.

## Limits

`WardrikLua.Sandbox.Runner` enforces the deadline and memory budget. The VM enforces the step
budget and call depth itself. See `WardrikLua.Sandbox.Limits`.

# `result`

```elixir
@type result() :: {:ok, term()} | {:error, String.t()}
```

The value the code returned, or why it failed.

# `check`

```elixir
@spec check(term()) :: :ok | {:error, String.t()}
```

Returns `:ok` if `code` can be run, without running it.

Returns an error if `code` isn't a string or is longer than 64 KB.

# `evaluate`

```elixir
@spec evaluate(String.t(), WardrikLua.Sandbox.Limits.t()) :: result()
```

Evaluates `code` in the calling process and returns its value.

Enforces only the limits the VM checks. Use `run/2` for the deadline and memory budget.

# `run`

```elixir
@spec run(String.t(), WardrikLua.Sandbox.Limits.t()) :: result()
```

Checks `code` with `check/1`, then evaluates it in a task of its own under `limits`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
