Packages

Core utilities for LushrLux

Current section

Files

Jump to
lushrlux lib helpers.ex
Raw

lib/helpers.ex

defmodule LushrLux.Core.Helpers do
@moduledoc """
Helpers is for functions that are going to transform data structurs
that are needed in ordered to make life of the dev life easier.
"""
@doc """
Atom map turns a string map into an atom map. This is used when some JSON comes into
an endpoint and then it's converted as it's just that little bit easier to work with atom maps.
## Example
iex> LushrLux.Core.Helpers.atom_map(%{"Elixir" => "Is cool"})
%{Elixir: "Is cool"}
"""
def atom_map(string_map) when is_map(string_map) do
for {k, v} <- string_map, into: %{}, do: {String.to_atom(k), v}
end
def atom_map(value), do: value
@doc """
String map does the opposit of `atom_map/1`. It takes an atom map and converts it to a string map.
This is useful when it comes to testing a POST endpoint.
It's easier to read and write an atom map and then just convert it here to mock the JSON that the endpoint
would see.
## Example
iex> LushrLux.Core.Helpers.string_map(%{Elixir: "Is cool"})
%{"Elixir" => "Is cool"}
"""
def string_map(atom_map) when is_map(atom_map) do
for {k, v} <- atom_map, into: %{}, do: {Atom.to_string(k), v}
end
def string_map(value), do: value
@doc """
When a query is passed to a GET endpoint that returns a collection of records such as `?location=Birmingham&asc=company_name`.
The `conn.params` are sent here to be turned into a list of 2 lists. The first list being a list of fields and a value, in this case
`location=Birmingham` and the second one being the sort by option where it detects the key of either `asc` or `desc` and the value, which
would be a field that needs to be sorted by.
This is all done so that the common method fir each table in the database referred to as `fetch/2`
will be able to work and correctly orientate the inputs and interpolate them correctly for valid SQL code.
## Example
iex> query = %{"asc" => "company_name", "location" => "Birmingham"}
...> LushrLux.Core.Helpers.parse_params(query)
[[location: "Birmingham"], [asc: :company_name]]
"""
def parse_params(%{} = params) do
sort = parse_sort_params(params)
params = Map.delete(params, "asc")
params = Map.delete(params, "desc")
search = for {key, val} <- params, into: [], do: {String.to_atom(key), val}
[search, sort]
end
defp parse_sort_params(%{} = params, result \\ []) do
case params do
%{"asc" => val} ->
parse_sort_params(Map.delete(params, "asc"), result ++ [{:asc, String.to_atom(val)}])
%{"desc" => val} ->
parse_sort_params(Map.delete(params, "desc"), result ++ [{:desc, String.to_atom(val)}])
_ ->
result
end
end
@doc """
Struct to json is as it sounds. It takes a struct, such as in servicer `%Servicer.User{first_name: "Jose", last_name: "Valim"}`.
Then it uses `Map.from_struct/1` and would convert it to `%{first_name: "Jose", last_name: "Valim"}`. From there it's able to be
encoded into a JSON version safe for returning.
This function can take a single struct or a list of structs.
"""
def struct_to_json(structs) when is_list(structs) do
Enum.map(structs, &struct_to_map/1) |> Jason.encode!()
end
def struct_to_json(%{} = struct) do
struct |> struct_to_map() |> Jason.encode!()
end
defp struct_to_map(%{} = struct) do
struct
|> Map.from_struct()
|> Map.drop([:__meta__])
end
end