Current section
Files
Jump to
Current section
Files
lib/ecto_context/paginator.ex
defmodule EctoContext.Paginator do
@moduledoc """
Pagination result struct containing entries, total count, and page metadata.
Returned by the `paginate/2` function generated by `EctoContext`.
Holds the current page's entries along with computed fields like
`total_pages`, `has_next_page?`, and `has_previous_page?`.
"""
@type t :: %__MODULE__{
entries: list(),
total: non_neg_integer(),
page: pos_integer(),
per_page: pos_integer(),
total_pages: non_neg_integer(),
has_next_page?: boolean(),
has_previous_page?: boolean()
}
defstruct [
:entries,
:total,
:page,
:per_page,
:total_pages,
:has_next_page?,
:has_previous_page?
]
@doc """
Creates a new `Paginator` struct from query results.
Normalizes `page` and `per_page` (accepts integers or string integers)
and computes `total_pages`, `has_next_page?`, and `has_previous_page?`.
"""
@spec new(list(), non_neg_integer(), term(), term()) :: t()
def new(entries, total, page, per_page) do
page = normalize_page(page)
per_page = normalize_per_page(per_page)
total_pages = if total == 0, do: 0, else: div(total + per_page - 1, per_page)
%__MODULE__{
entries: entries,
total: total,
page: page,
per_page: per_page,
total_pages: total_pages,
has_next_page?: page < total_pages,
has_previous_page?: page > 1
}
end
defp normalize_page(val) when is_integer(val), do: max(1, val)
defp normalize_page(val) when is_binary(val), do: val |> String.to_integer() |> max(1)
defp normalize_page(_), do: 1
defp normalize_per_page(val) when is_integer(val), do: max(1, val)
defp normalize_per_page(val) when is_binary(val), do: val |> String.to_integer() |> max(1)
defp normalize_per_page(_), do: 20
end