defmodule Lob.ResourceBase do @moduledoc """ Module representing the base Lob resource. """ defmacro __using__(opts) do endpoint = Keyword.fetch!(opts, :endpoint) methods = Keyword.fetch!(opts, :methods) quote do @default_api_host "https://api.lob.com/v1" alias Lob.Client alias Lob.Util if :list in unquote(methods) do @spec list(map, map) :: Client.client_response def list(params \\ %{}, headers \\ %{}) do Client.get_request("#{base_url()}?#{Util.build_query_string(params)}" , Util.build_headers(headers)) end @spec list!(map, map) :: {map, list} | no_return def list!(params \\ %{}, headers \\ %{}) do case list(params, headers) do {:ok, body, headers} -> {body, headers} {:error, error} -> raise to_string(error) end end end if :retrieve in unquote(methods) do @spec retrieve(String.t, map) :: Client.client_response def retrieve(id, headers \\ %{}) do Client.get_request(resource_url(id), Util.build_headers(headers)) end @spec retrieve!(String.t, map) :: {map, list} | no_return def retrieve!(id, headers \\ %{}) do case retrieve(id, headers) do {:ok, body, headers} -> {body, headers} {:error, error} -> raise to_string(error) end end end if :create in unquote(methods) do @spec create(map, map) :: Client.client_response def create(data, headers \\ %{}) do Client.post_request(base_url(), Util.build_body(data), Util.build_headers(headers)) end @spec create!(map, map) :: {map, list} | no_return def create!(data, headers \\ %{}) do case create(data, headers) do {:ok, body, headers} -> {body, headers} {:error, error} -> raise to_string(error) end end end if :delete in unquote(methods) do @spec delete(String.t, map) :: Client.client_response def delete(id, headers \\ %{}) do Client.delete_request(resource_url(id), Util.build_headers(headers)) end @spec delete!(String.t, map) :: {map, list} | no_return def delete!(id, headers \\ %{}) do case delete(id, headers) do {:ok, body, headers} -> {body, headers} {:error, error} -> raise to_string(error) end end end @spec base_url :: <<_::64, _::_*8>> defp base_url do "#{api_host()}/#{unquote(endpoint)}" end @spec api_host :: <<_::64, _::_*8>> defp api_host do "#{Application.get_env(:lob_elixir, :api_host, @default_api_host)}" end @spec resource_url(String.t) :: <<_::64, _::_*8>> defp resource_url(resource_id) do "#{base_url()}/#{resource_id}" end end end end