Current section
Files
Jump to
Current section
Files
lib/request_params_checker.ex
defmodule EXRequest.ParamsChecker do
@moduledoc """
Checks that the function name and params are correct for the definition and invocation
"""
@doc """
Check if the function has any parameters
* `url` - The url used to invoke the function
* `headers` - The headers used to invoke the function
* `query` - The query keys used to invoke the function
"""
def check_has_params(url: url, headers: headers, query: query) do
url_params = url_params(url)
header_params = headers
|> Keyword.values
|> filter_header_keys
length(header_params ++ url_params ++ query) > 0
end
@doc """
Checks that the function invocation with the parameters is correctly defined for the URL and Header keys
Parameters:
* `function_name` - The function name used
* `function_params` - The function parameters used in invocation
* `url` - The url used to invoke the function
* `header_keys` - The headers used to invoke the function
"""
def check_invocation_params(function_name, function_params, url, header_keys, has_client \\ true) do
function_params = function_params -- [:body, :decoder]
prefix = prefix_for_client(has_client)
case check_params(url, header_keys, function_params) do
{:error, _} ->
invoked_func = propsed_method_invocation(prefix, func_name: function_name, params: function_params)
correct_func = propsed_method_invocation(func_name: function_name, url: url, header_keys: header_keys)
{:error,
"\n\n" <>
"""
You are trying to call the wrong function:
#{invoked_func}
Please instead call:
#{correct_func}
"""}
:ok -> :ok
end
end
defp prefix_for_client(false), do: nil
defp prefix_for_client(has_client), do: "client"
@doc """
Checks that the url, header_keys and function parameters match
Parameters:
* `url` - The url used to invoke the function
* `header_params` - The headers used to invoke the function
* `params` - The function parameters used in invocation
"""
def check_params(url, header_params, params) do
params = params || []
keys_passed = params |> Enum.map(&to_string/1)
header_params = header_params
|> filter_header_keys
|> Enum.map(&to_string/1)
required_params = url_params(url) ++ header_params
[missing: required_params -- keys_passed,
extra: keys_passed -- required_params]
|> adjust_params
end
@doc """
Get the proposed method invocation
Parameters:
* `func_name` - The function name used
* `url` - The url used to invoke the function
"""
def propsed_method_invocation(prefix \\ "client", other)
def propsed_method_invocation(prefix, func_name: func_name, url: url) do
propsed_method_invocation(prefix, func_name: func_name, params: url_params(url))
end
@doc """
Get the proposed method definition
Parameters:
* `func_name` - The function name used
* `url` - The url used to invoke the function
* `header_keys` - The header keys used to invoke the function
"""
def propsed_method_invocation(prefix, func_name: func_name, url: url, header_keys: header_keys) do
header_keys = header_keys |> filter_header_keys
propsed_method_invocation(prefix, func_name: func_name, params: url_params(url) ++ header_keys)
end
@doc """
Get the proposed method definition
Parameters:
* `func_name` - The function name used
* `params` - The parameters used in the function
"""
def propsed_method_invocation(prefix, func_name: func_name, params: params) do
all_params = [prefix , proposed_params(for_params: params)]
|> Enum.filter(fn item -> item != "" end)
|> Enum.join(", ")
"#{func_name}(#{all_params})"
end
@doc """
Get an error string for missing and extra params
Parameters:
* `missing` - The missing parameters in the definition
* `extra` - The extra parameters in the definition
"""
def definition_param_error_report(missing: [], extra: []), do: :ok
def definition_param_error_report(missing: missing_params, extra: extra_params) do
errors = []
if missing_params != [] do
errors = errors ++ ["- Parameters [#{Enum.join(missing_params, ", ")}] are missing from function definition"]
end
if extra_params != [] do
errors = errors ++ ["- Parameters [#{Enum.join(extra_params, ", ")}] are ignored in the function definition"]
end
{:error, errors |> Enum.join("\n")}
end
@doc """
Get url parametrs from a url
"""
def url_params(url) do
Regex.scan(~r/{.*}/r, url)
|> Enum.map(fn ([i]) -> String.slice(i, 1..-2) end)
end
defp filter_header_keys(header_keys) do
header_keys |> Enum.filter(fn item ->
is_atom(item)
end)
end
defp proposed_params(for_params: []) do
""
end
defp proposed_params(for_params: params) do
Enum.reduce(params, "", fn param, acc-> acc <> "#{param}: #{param}, " end)
|> String.slice(0..-3)
end
defp adjust_params(missing: [], extra: []), do: :ok
defp adjust_params(params), do: {:error, params}
end