defmodule Warlock.Siren.Links do
alias Warlock.Siren.Links
alias Warlock.Utils
alias Plug.Conn
def parse_uri(conn), do: conn |> Conn.request_url() |> URI.parse()
def decode_query(%{query: nil}), do: %{}
def decode_query(url), do: url |> Map.get(:query) |> URI.decode_query()
def make(rel, href), do: %{rel: [rel], href: href}
@doc """
Creates an updated uri to a new page.
"""
def change_page(conn, new_page) do
url = Links.parse_uri(conn)
query =
url
|> Links.decode_query()
|> Map.put("page", new_page)
|> URI.encode_query()
url
|> Map.put(:query, query)
|> URI.to_string()
end
@doc """
Adds a link to the next page, if it's not the last page.
"""
def add_next(links, conn, count) do
page = Utils.get_page(conn)
items = Utils.get_items(conn)
if page * items < count do
[Links.make("next", Links.change_page(conn, page + 1)) | links]
else
links
end
end
@doc """
Adds a link to the last page
"""
def add_last(links, conn, count) do
last_page = ceil(count / Utils.get_items(conn))
[Links.make("last", Links.change_page(conn, last_page)) | links]
end
@doc """
Adds a link to the previous page, if it's not the first page.
"""
def add_prev(links, %{query_params: %{"page" => current_page}} = conn) do
page = String.to_integer(current_page)
if page == 1 do
links
else
[Links.make("prev", Links.change_page(conn, page - 1)) | links]
end
end
def add_prev(links, _conn), do: links
def add_self(links, conn) do
[Links.make("self", Conn.request_url(conn)) | links]
end
def add_first(links, conn) do
[Links.make("first", Links.change_page(conn, 1)) | links]
end
end