Skip to content

Commit

Permalink
Merge pull request #4 from tv-labs/readme
Browse files Browse the repository at this point in the history
Start writing some module docs
  • Loading branch information
davydog187 authored Mar 7, 2024
2 parents cbd8f27 + 5ea04f5 commit 85b1e2d
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 15 deletions.
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
# Lua

Brings all the expected UX of Elixir to Luerl
<!-- MDOC !-->

Lua is an ergonomic interface to [Luerl](https://github.com/rvirding/luerl), aiming to be the best way to use Luerl from Elixir.

## Features

* Ergonomic API for Elixir <> Lua FFI
* Improved error messages
* Deep-setting variables and state
* Excellent documentation and guides for working with Luerl

## Usage

### Executing Lua

Lua can be run using the `eval!/2` function

``` elixir
iex> {[4], _} =
...> Lua.eval!("""
...> return 2 + 2
...> """)
```
### Exposing Elixir functions to Lua
`Lua` provides the `deflua` macro for exposing Elixir functions to Lua
defmodule MyAPI do
use Lua.API
deflua double(v), do: 2 * v
end
lua = Lua.new() |> Lua.load_api(MyAPI)
{[10], _} =
Lua.eval!(lua, """
return double(5)
""")
12 changes: 7 additions & 5 deletions lib/lua.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
defmodule Lua do
@moduledoc """
Lua aims to be the best way to integrate Luerl into an Elixir project.
"""
@external_resource "README.md"
@moduledoc @external_resource
|> File.read!()
|> String.split("<!-- MDOC !-->")
|> Enum.fetch!(1)

defstruct [:state, functions: %{}]

Expand Down Expand Up @@ -218,9 +220,9 @@ defmodule Lua do
Inject functions written with the `deflua` macro into the Lua
runtime
"""
# TODO rename to load_api
def inject_module(lua, module, scope \\ []) do
def load_api(lua, module, scope \\ nil) do
funcs = :functions |> module.__info__() |> Enum.group_by(&elem(&1, 0), &elem(&1, 1))
scope = scope || module.scope()

module.__lua_functions__()
|> Enum.reduce(lua, fn {name, with_state?, variadic?}, lua ->
Expand Down
4 changes: 2 additions & 2 deletions test/lua/api_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule Lua.APITest do
end
""")

lua = Lua.inject_module(Lua.new(), module, module.scope())
lua = Lua.load_api(Lua.new(), module)

assert {["Whoa, check this out!"], _} =
Lua.eval!(lua, """
Expand All @@ -41,7 +41,7 @@ defmodule Lua.APITest do
end
""")

lua = Lua.inject_module(Lua.new(), module, module.scope())
lua = Lua.load_api(Lua.new(), module)

assert {["starting value", 111], _} =
Lua.eval!(lua, """
Expand Down
14 changes: 7 additions & 7 deletions test/lua_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ defmodule LuaTest do
end
end

lua = Lua.inject_module(Lua.new(), Test, Test.scope())
lua = Lua.load_api(Lua.new(), Test)

error = "Lua runtime error: test.foo() failed, expected 1 arguments, got 2"

Expand Down Expand Up @@ -278,7 +278,7 @@ defmodule LuaTest do
end
end

describe "inject_module/2 and inject_module/3" do
describe "load_api/2 and load_api/3" do
defmodule TestModule do
use Lua.API

Expand All @@ -297,22 +297,22 @@ defmodule LuaTest do
end

test "injects a global Elixir module functions into the Lua runtime", %{lua: lua} do
lua = Lua.inject_module(lua, TestModule)
lua = Lua.load_api(lua, TestModule)
assert {["test"], _} = Lua.eval!(lua, "return foo('test')")
end

test "injects a scoped Elixir module functions into the Lua runtime", %{lua: lua} do
lua = Lua.inject_module(lua, TestModule, ["scope"])
lua = Lua.load_api(lua, TestModule, ["scope"])
assert {["test"], _} = Lua.eval!(lua, "return scope.foo('test')")
end

test "inject a variadic function", %{lua: lua} do
lua = Lua.inject_module(lua, TestModule, ["scope"])
lua = Lua.load_api(lua, TestModule, ["scope"])
assert {["a-b-c"], _} = Lua.eval!(lua, "return scope.bar('a', 'b', 'c')")
end

test "injects Elixir functions that have multiple arities", %{lua: lua} do
lua = Lua.inject_module(lua, TestModule, ["scope"])
lua = Lua.load_api(lua, TestModule, ["scope"])

assert {["a default"], _} = Lua.eval!(lua, "return scope.test(\"a\")")
assert {["a b"], _} = Lua.eval!(lua, "return scope.test(\"a\", \"b\")")
Expand Down Expand Up @@ -369,7 +369,7 @@ defmodule LuaTest do
end

setup do
%{lua: Lua.new() |> Lua.inject_module(Examples, ["example"])}
%{lua: Lua.new() |> Lua.load_api(Examples, ["example"])}
end

test "can work with numbers", %{lua: lua} do
Expand Down

0 comments on commit 85b1e2d

Please sign in to comment.