Packages

Pivo is an Elixir interface for the Pivotal Tracker REST API V5.

Current section

Files

Jump to
pivo lib pivo endpoint.ex
Raw

lib/pivo/endpoint.ex

defmodule Pivo.Endpoint do
@moduledoc """
Endpoint behaviour module.
Sets the endpoint configuration.
This module is meant to be `use`'d in custom modules in order to support different
endpoints of the Pivotal's Tracker API.
Receives a `params` keyword list with the following keys:
- Required
+ `path` - String
+ `http_methods` - list of triplets {action_verb, context, params}
- Optional
+ `path_params` - keyword list
## Example
defmodule Pivo.MeEndpoint do
use Pivo.Endpoint,
path: "/me",
http_methods: [
{:get, [resource: Me], []}
]
end
"""
@type t :: module()
@typep params :: Keyword.t()
@doc """
Returns the current endpoint `path`.
"""
@callback path() :: String.t()
@doc """
Returns the current endpoint `path_params`.
"""
@callback path_params() :: params()
defmacro __using__(options) do
path = Keyword.get(options, :path, "/")
path_params = Keyword.get(options, :path_params, [])
http_methods = Keyword.get(options, :http_methods, [])
quote bind_quoted: [
path: path,
path_params: path_params,
http_methods: http_methods
],
location: :keep do
@behaviour Pivo.Endpoint
@impl true
def path, do: unquote(path)
@impl true
def path_params, do: unquote(path_params)
end
end
@doc """
Builds the `url_path` for a given `Pivo.Endpoint` using the provided parameters.
"""
def build_path_with_params(endpoint, path_params) do
string_path_params = stringify_path_params(endpoint.path_params(), path_params)
Enum.reduce(string_path_params, endpoint.path(), fn {param_key, param_string_value}, url ->
String.replace(url, ~r/({#{Atom.to_string(param_key)}})/, param_string_value)
end)
end
defp stringify_path_params(params_def, params_val) do
for {param_key, param_type} <- params_def do
case Keyword.fetch(params_val, param_key) do
{:ok, value} ->
{param_key, path_param_to_string(param_type, value)}
:error ->
raise ArgumentError,
message: "invalid argument path_params, missing required parameter: #{param_key}"
end
end
end
defp path_param_to_string(:integer, value) when is_integer(value) do
Integer.to_string(value)
end
defp path_param_to_string(_, value) do
to_string(value)
end
end