Current section
Files
Jump to
Current section
Files
lib/jsonapi_kit/query/sort_builder.ex
defmodule Solage.QuerySortBuilder do
@moduledoc """
Parse the `sort` param to return a sane representation of all the sort.
The representation looks like this and is meant to be understood by the Ecto library.
```
[desc: :field1, asc: :field2]
```
It can also reject unallowed sort.
If the `allowed_sort` options is not passed, that means that every sort is allowed.
## Examples
```
# With no options
iex> Solage.QuerySortBuilder.build("inserted_at,description", %Solage.QueryConfig{})
[asc: :inserted_at, asc: :description]
# With allowed sort option
iex> Solage.QuerySortBuilder.build("inserted_at,description", %Solage.QueryConfig{options: [allowed_sort: ~w(description)]})
[asc: :description]
```
"""
@behaviour Solage.QueryBuilder
@sort_separator ","
def build(nil, _config), do: []
def build("", _config), do: []
def build(param, config) do
param
|> String.split(@sort_separator)
|> reject_unallowed_sort(config)
|> Enum.map(&parse_sort/1)
end
defp parse_sort("-" <> attribute), do: {:desc, String.to_atom(attribute)}
defp parse_sort(attribute), do: {:asc, String.to_atom(attribute)}
defp reject_unallowed_sort(items, config) do
case config.options[:allowed_sort] do
nil -> items
allowed_sort ->
items
|> Enum.reject(fn
("-" <> item) ->
not Enum.member?(allowed_sort, item)
item ->
not Enum.member?(allowed_sort, item)
end)
end
end
end