defmodule Mixpanel.Config do
@moduledoc """
Module that helps handling configuration values provided by a user.
"""
@type project_token :: String.t()
@type base_url :: String.t()
@type http_adapter :: Mixpanel.HTTP.HTTPC | Mixpanel.HTTP.Hackney | Mixpanel.HTTP.NoOp
@type name :: atom
@type option ::
{:project_token, project_token}
| {:base_url, base_url}
| {:http_adapter, http_adapter}
| {:name, name}
@type options :: [option, ...]
@base_url "https://api.mixpanel.com"
@known_adapters [Mixpanel.HTTP.HTTPC, Mixpanel.HTTP.Hackney, Mixpanel.HTTP.NoOp]
@doc false
@spec clients() :: [{name, options}]
def clients() do
for {name, config} <- Application.get_all_env(:mixpanel_api_ex) do
{name, client(name, config)}
end
end
@doc """
Helper that validates user provided configuration and substitutes default
parameters when needed.
## Examples
iex> Mixpanel.Config.client(MyApp.Mixpanel, [project_token: "token"])
[
http_adapter: Mixpanel.HTTP.HTTPC,
base_url: "https://api.mixpanel.com",
name: MyApp.Mixpanel,
project_token: "token"
]
"""
@doc export: true
@spec client(name, options) :: options | nil
def client(name, opts) when is_atom(name) and is_list(opts) do
opts
|> Keyword.put_new(:name, name)
|> Keyword.put_new(:base_url, @base_url)
|> Keyword.put_new(:http_adapter, Mixpanel.HTTP.HTTPC)
|> validate_http_adapter!()
|> Keyword.take([:name, :base_url, :http_adapter, :project_token])
end
def client(name, _) when not is_atom(name),
do: raise(ArgumentError, "Expected a module name as a client name, got #{inspect(name)}")
def client(_, _), do: nil
defp validate_http_adapter!(config) do
case config[:http_adapter] do
http_adapter when http_adapter in @known_adapters ->
config
http_adapter ->
raise(ArgumentError, "Expected a valid http adapter, got #{inspect(http_adapter)}")
end
end
end