accessor v0.1.0 Accessor

Accessor is an Elixir data structure manipulator wrapper

Link to this section Summary

Functions

Get a value from a very deep nested map or list

Update a value in a very deep nested map or list

Map or list value validation. The function is very useful to check a value under a very deep and nested map or list.

Link to this section Functions

Link to this function

deep_get(data, keys, default \\ nil)

deep_get(map() | list(), list(), any()) :: any()

Get a value from a very deep nested map or list

iex> Accessor.deep_get(%{bio: %{name: %{first: "irfan", last: "hanif"}, age: 22}, position: "software engineer"}, [:bio, :name, :last])
"hanif"
iex> Accessor.deep_get(%{bio: %{name: %{first: "irfan", last: "hanif"}, age: 22}, position: "software engineer"}, [:bio, :name, :middle], "power ranger")
"power ranger"
Link to this function

deep_put(data, keys, value)

deep_put(map() | list(), list(), any()) :: map() | list()

Update a value in a very deep nested map or list

iex> Accessor.deep_put(%{a: %{"b" => %{c: 42}}}, [:a, "b", :c], 177)
%{a: %{"b" => %{c: 177}}}

iex> Accessor.deep_put(%{a: %{"b" => %{c: [42, 43, 44]}}}, [:a, "b", :c, 1], 177)
%{a: %{"b" => %{c: [42, 177, 44]}}}
Link to this function

validation(data, spec)

validation(map() | list(), map()) :: :ok | {:error, [String.t()]}

Map or list value validation. The function is very useful to check a value under a very deep and nested map or list.

Evaluate these following functions:

# This is the spec that will be used as reference to validate data within a map or list
def spec do
  %{
    [:bio, "name", "first"] => [:is_it_string],
    [:bio, :age] => [:is_it_integer],
    [:position, 0] => [&is_it_software_engineer/2]
  }
end

# This is a custom validator function
def is_it_software_engineer(keys, value) do
  if value == "software engineer" do
    :ok
  else
    {:error, "#{Enum.join(keys, ".")} is not a software engineer"}
  end
end

These are the results when you call the function:

iex> data =
...>    %{
...>      bio: %{
...>        "name" => %{"first" => "irfan", "last" => "hanif"}, age: 22
...>      }, 
...>      position: ["software engineer", "junior architect"]
...>    }
iex> Accessor.validation(data, spec)
:ok

iex> data =
...>    %{
...>      bio: %{
...>        "name" => %{"first" => 112548, "last" => "hanif"}, age: 22
...>      }, 
...>      position: ["software developer", "junior architect"]
...>    }
iex> Accessor.validation(data, spec)
{:error, ["bio.name.first is not a string", "position.0 is not a software engineer"]}

This is a list of built-in validator function which you can use directly:

  • :is_it_string to check whether a value is in the form of string
  • :is_it_integer to check whether a value is in the form of integer
  • :is_it_boolean to check whether a value is in the form of boolean

As you can see, it is possible for you to use your own custom validator. If you choose to make your own validator, the function must be capable of receiving two arguments keys and value and two returns possibilities: :ok or {:error, error_message}. At example above, is_it_software_engineer/2 is a custom function validator.