Packages
surgex
6.0.1
6.0.1
6.0.0
5.1.1
5.1.0
5.0.0
5.0.0-git-015aa39a
4.15.2
4.15.1
4.15.1-git-98b3
4.15.0
4.15.0-git-943e
4.15.0-git-5806
4.14.1
4.14.0
4.13.1
4.13.0
4.12.0
4.11.0
4.11.0-git-97d4
4.11.0-git-14c8
4.10.0
4.10.0-git-37f2
4.9.0
4.9.0-git-9d5f
4.8.1-git-80a7
4.8.0
4.8.0-git-fbda
4.8.0-git-e058
4.7.0
4.7.0-git-5414
4.6.1
4.6.0
4.5.0
4.4.0
4.3.0
4.2.1
4.2.0
4.1.1
4.1.1-git-9f6b
4.1.1-git-6f0cd
4.1.0
4.1.0-git-e934
4.1.0-git-8c28
4.1.0-git-56a9
4.1.0-git-55fd
4.0.0
3.2.8
3.2.7
3.2.6
3.2.5
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
retired
3.1.0
3.0.0
2.24.1
2.24.0
retired
2.23.0
2.22.0
2.21.0
2.20.1
2.20.0
2.19.0
2.18.1
2.18.0
2.17.0
2.16.0
2.15.0
2.14.0
2.13.0
2.12.1
2.12.0
2.11.0
2.10.0
2.9.0
2.8.0
2.7.0
2.6.0
2.5.1
2.5.0
2.4.0
retired
2.3.0
2.2.1
2.2.0
2.1.1
2.1.0
2.0.0
1.6.0
1.5.2
1.5.1
1.5.0
1.4.0
1.3.1
retired
1.3.0
retired
1.2.1
1.2.0
1.1.0
1.0.0
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
All Things Elixir @ Surge Ventures Inc, the creators of Fresha
Current section
Files
Jump to
Current section
Files
lib/surgex/parser/parsers/sort_parser.ex
defmodule Surgex.Parser.SortParser do
@moduledoc """
Parses the JSON API's sort parameter according to the
[JSON API spec](http://jsonapi.org/format/#fetching-sorting).
Produces a `{direction, column}` tuple, in which `direction` is either `:asc` or `:desc` and
`column` is a safely atomized and underscored column name.
"""
@doc false
@spec call(term(), [atom]) :: {:ok, {:asc | :desc, atom} | nil} | {:error, :invalid_sort_column}
def call(nil, _allowed_columns), do: {:ok, nil}
def call("", _allowed_columns), do: {:ok, nil}
def call(input, allowed_columns) when is_binary(input) do
case input do
"-" <> column ->
validate_allowed_columns(column, allowed_columns, :desc)
column ->
validate_allowed_columns(column, allowed_columns, :asc)
end
end
def call(_input, _), do: {:error, :invalid_sort_column}
defp validate_allowed_columns(column, allowed_columns, direction) do
column_atom = atomize_maybe_dasherized(column)
if column_atom && column_atom in allowed_columns do
{:ok, {direction, column_atom}}
else
{:error, :invalid_sort_column}
end
end
defp atomize_maybe_dasherized(string) do
atomize(string) ||
string
|> String.replace("-", "_")
|> atomize
end
defp atomize(string) do
String.to_existing_atom(string)
rescue
ArgumentError -> nil
end
@doc """
Flattens the result of the parser (sort tuple) into `*_by` and `*_direction` keys.
## Examples
iex> SortParser.flatten({:ok, sort: {:asc, :col}}, :sort)
{:ok, sort_by: :col, sort_direction: :asc}
"""
@spec flatten({:ok, Keyword.t()}, atom) :: {:ok, {:asc | :desc, atom}}
def flatten({:ok, opts}, key) do
case Keyword.pop(opts, key) do
{nil, _} ->
{:ok, opts}
{{direction, column}, rem_opts} ->
final_opts = Keyword.merge(rem_opts, sort_by: column, sort_direction: direction)
{:ok, final_opts}
end
end
def flatten(input, _key), do: input
end