Packages

Elixir library for various strategies/experiments for avoiding string access to conn params

Current section

Files

Jump to
indifferent_access lib params.ex
Raw

lib/params.ex

defmodule IndifferentAccess.Params do
alias __MODULE__
@moduledoc """
This struct has two behaviors, the default where any map returned from its Access methods
will also be a Params struct, or if `strategy: :static` is passed as an option, it will only set the top level
params as a struct and any returned values will be unchanged.
"""
defstruct params: %{}, opts: []
@behaviour Access
def new(params, opts \\ [strategy: :replace]) do
%Params{params: params, opts: opts}
end
@impl Access
def fetch(%Params{params: params, opts: opts}, key) when is_atom(key) do
initial_value = Map.fetch(params, key)
return_value =
if initial_value != :error, do: initial_value, else: Map.fetch(params, to_string(key))
wrap(return_value, opts[:strategy])
end
def fetch(%Params{params: params, opts: opts}, key) do
wrap(Map.fetch(params, key), opts[:strategy])
end
def get(container, key, default \\ nil)
def get(%Params{params: params, opts: opts}, key, default) when is_atom(key) do
initial_value = Map.get(params, key, default)
return_value =
if initial_value, do: initial_value, else: Map.get(params, to_string(key), default)
wrap(return_value, opts[:strategy])
end
def get(%Params{params: params, opts: opts}, key, default) do
wrap(Map.get(params, key, default), opts[:strategy])
end
@impl Access
def get_and_update(%Params{params: params, opts: opts}, key, fun) when is_atom(key) do
initial_value = Map.get(params, key)
update_key = if initial_value, do: key, else: to_string(key)
{get_value, new_params} = Map.get_and_update(params, update_key, fun)
{wrap(get_value, opts[:strategy]), %__MODULE__{params: new_params}}
end
def get_and_update(%Params{params: params, opts: opts}, key, fun) do
{get_value, new_params} = Map.get_and_update(params, key, fun)
{wrap(get_value, opts[:strategy]), %__MODULE__{params: new_params}}
end
@impl Access
def pop(container, key, default \\ nil)
def pop(%Params{params: params, opts: opts}, key, default) when is_atom(key) do
initial_value = Map.get(params, key)
pop_key = if initial_value, do: key, else: to_string(key)
{get_value, new_params} = Map.pop(params, pop_key, default)
{wrap(get_value, opts[:strategy]), %__MODULE__{params: new_params}}
end
def pop(%Params{params: params, opts: opts}, key, default) do
{get_value, new_params} = Map.pop(params, key, default)
{wrap(get_value, opts[:strategy]), %__MODULE__{params: new_params}}
end
defp wrap(any, :static), do: any
defp wrap(map, :replace) when is_map(map) do
new(map)
end
defp wrap(list, :replace) when is_list(list) do
for item <- list, do: wrap(item, :replace)
end
defp wrap({:ok, any}, :replace) do
{:ok, wrap(any, :replace)}
end
defp wrap(other, :replace), do: other
end