farmbot_os/farmbot_os/lib/farmbot_os/lua.ex

57 lines
1.5 KiB
Elixir

defmodule FarmbotOS.Lua do
@type t() :: tuple()
@type table() :: [{any, any}]
alias FarmbotOS.Lua.CeleryScript
@doc """
Evaluates some Lua code. The code should
return a boolean value.
"""
def eval_assertion(str) when is_binary(str) do
init()
|> set_table([:get_position], &CeleryScript.get_position/2)
|> set_table([:get_pins], &CeleryScript.get_pins/2)
|> set_table([:send_message], &CeleryScript.send_message/2)
|> set_table([:help], &CeleryScript.help/2)
|> set_table([:version], &CeleryScript.version/2)
|> eval(str)
|> case do
{:ok, [true | _]} ->
true
{:ok, [false | _]} ->
false
{:ok, [_, reason]} when is_binary(reason) ->
{:error, reason}
{:ok, _data} ->
{:error, "bad return value from expression evaluation"}
{:error, {:lua_error, _error, _lua}} ->
{:error, "lua runtime error evaluating expression"}
{:error, {:badmatch, {:error, [{line, :luerl_parse, parse_error}], _}}} ->
{:error, "failed to parse expression (line:#{line}): #{IO.iodata_to_binary(parse_error)}"}
error ->
error
end
end
@spec init() :: t()
def init do
:luerl.init()
end
@spec set_table(t(), Path.t(), any()) :: t()
def set_table(lua, path, value) do
:luerl.set_table(path, value, lua)
end
@spec eval(t(), String.t()) :: {:ok, any()} | {:error, any()}
def eval(lua, hook) when is_binary(hook) do
:luerl.eval(hook, lua)
end
end