Current section

Files

Jump to
concerto lib concerto.ex
Raw

lib/concerto.ex

defmodule Concerto do
defmacro __using__(opts) do
quote bind_quoted: binding do
root = opts[:root] || "web"
ext = opts[:ext] || ".exs"
resources = root
|> Path.join("**/*#{ext}")
|> Path.wildcard()
methods = (opts[:methods] || ["GET", "POST", "PUT", "DELETE", "PATCH"])
|> Enum.map(fn
({key, value}) when is_binary(key) ->
{key, value}
(key) when is_binary(key) ->
{key, key}
end)
|> Enum.into(%{})
prefix = opts[:module_prefix] || __MODULE__
locations = Concerto.Utils.format_locations(resources, root, ext, methods)
@doc """
Lookup the module for the provided method and parts
iex> #{inspect(__MODULE__)}.match("GET", [])
{#{inspect(prefix)}.GET, %{}}
iex> #{inspect(__MODULE__)}.match("POST", ["users", "123"])
{#{inspect(prefix)}.Users.User_.POST, %{"user" => "123"}}
"""
def match(method, parts)
@doc """
Resolve the method and path given the route name and params
iex> #{inspect(__MODULE__)}.resolve("GET /")
{"GET", []}
iex> #{inspect(__MODULE__)}.resolve("POST /users/@user", %{"user" => "123"})
{"POST", ["users", "123"]}
"""
def resolve(name, params \\ %{})
@doc """
Lookup the module for the given name
iex> #{inspect(__MODULE__)}.resolve_module("GET /")
#{inspect(prefix)}.GET
iex> #{inspect(__MODULE__)}.resolve_module("POST /users/@user")
#{inspect(prefix)}.Users.User_.POST
"""
def resolve_module(name)
for {file, method, mapped_method, path} <- locations do
name = method <> " /" <> Enum.join(path, "/")
module = Concerto.Utils.format_module(prefix, path, method)
{parts, params} = Concerto.Utils.format_parts(path)
def match(unquote(method), unquote(parts)) do
{unquote(module), %{unquote_splicing(params)}}
end
def resolve(unquote(file), %{unquote_splicing(params)}) do
{unquote(mapped_method), unquote(parts)}
end
def resolve(unquote(name), %{unquote_splicing(params)}) do
{unquote(mapped_method), unquote(parts)}
end
def resolve(unquote(module), %{unquote_splicing(params)}) do
{unquote(mapped_method), unquote(parts)}
end
def resolve_module(unquote(file)) do
unquote(module)
end
def resolve_module(unquote(name)) do
unquote(module)
end
end
def match(_, _), do: nil
def resolve(_, _), do: nil
def resolve_module(_), do: nil
def reload do
Code.load_file(__ENV__.file)
end
end
end
end