Packages

GRPC builder helps to generate the GRPC client and server code.

Current section

Files

Jump to
grpc_builder lib client builder.ex
Raw

lib/client/builder.ex

defmodule GrpcBuilder.Client.Builder do
@moduledoc """
Macro for building RPC easily
"""
alias GrpcBuilder.Client.Helper
defmacro __using__(_) do
quote do
import GrpcBuilder.Client.Builder, only: [rpc: 3, rpc: 2]
Module.register_attribute(__MODULE__, :rpc_app, persist: true)
end
end
defmacro rpc(service, options, contents \\ []) do
compile(service, options, contents)
end
# credo:disable-for-lines:55
defp compile(service, options, contents) do
{body, options} =
cond do
Keyword.has_key?(contents, :do) ->
{contents[:do], options}
Keyword.has_key?(options, :do) ->
Keyword.pop(options, :do)
true ->
raise ArgumentError, message: "expected :do to be given as option"
end
mod = to_request_mod(service, Macro.to_string(options[:prefix]))
quote bind_quoted: [
mod: mod,
service: service,
options: options,
body: Macro.escape(body, unquote: true)
] do
default_opts = options[:opts] || []
rpc_app = Module.get_attribute(__MODULE__, :rpc_app)
cond do
options[:request_stream] == true ->
def unquote(service)(reqs, name \\ "", opts \\ []) do
conn = Helper.get_conn(unquote(rpc_app), name)
reqs = Helper.to_req(reqs, unquote(mod))
fun = fn var!(res) -> unquote(body) end
opts = Keyword.merge(unquote(default_opts), opts)
Helper.send_stream(unquote(service), conn, reqs, opts, fun)
end
options[:response_stream] == true and options[:no_params] == true ->
def unquote(service)(name \\ "", opts \\ []) do
conn = Helper.get_conn(unquote(rpc_app), name)
req = apply(unquote(mod), :new, [])
fun = fn var!(res) -> unquote(body) end
opts = Keyword.merge(unquote(default_opts), opts)
Helper.send(unquote(service), conn, req, opts, fun)
end
options[:response_stream] == true ->
def unquote(service)(req, name \\ "", opts \\ []) do
conn = Helper.get_conn(unquote(rpc_app), name)
req = Helper.to_req(req, unquote(mod))
fun = fn var!(res) -> unquote(body) end
opts = Keyword.merge(unquote(default_opts), opts)
Helper.send(unquote(service), conn, req, opts, fun)
end
options[:no_params] == true ->
def unquote(service)(name \\ "", opts \\ []) do
conn = Helper.get_conn(unquote(rpc_app), name)
req = apply(unquote(mod), :new, [])
fun = fn var!(res) -> unquote(body) end
opts = Keyword.merge(unquote(default_opts), opts)
Helper.send(unquote(service), conn, req, opts, fun)
end
true ->
def unquote(service)(req, name \\ "", opts \\ []) do
conn = Helper.get_conn(unquote(rpc_app), name)
req = Helper.to_req(req, unquote(mod))
fun = fn var!(res) -> unquote(body) end
opts = Keyword.merge(unquote(default_opts), opts)
Helper.send(unquote(service), conn, req, opts, fun)
end
end
end
end
defp to_request_mod(service, prefix) do
name =
service
|> Atom.to_string()
|> Recase.to_pascal()
Module.concat(prefix, "Request#{name}")
end
end