defmodule Ravix.Documents.Session.Validations do
@moduledoc """
Validation rules for session states
"""
alias Ravix.Documents.Session.State, as: SessionState
@doc """
Returns an error if the document is in a deferred command
"""
@spec document_not_in_deferred_command(SessionState.t(), binary()) ::
{:ok, binary()} | {:error, :document_already_deferred}
def document_not_in_deferred_command(%SessionState{} = state, entity_id) do
state.defer_commands
|> Enum.find_value({:ok, entity_id}, fn elmn ->
if elmn.key == entity_id, do: {:error, :document_already_deferred}
end)
end
@doc """
Returns an error if the document is already marked for deletion
"""
@spec document_not_deleted(SessionState.t(), binary()) ::
{:ok, binary()} | {:error, :document_deleted}
def document_not_deleted(%SessionState{} = state, entity_id) do
state.deleted_entities
|> Enum.find_value({:ok, entity_id}, fn elmn ->
if elmn.key == entity_id, do: {:error, :document_deleted}
end)
end
@doc """
Returns an error if the document is already stored in the session
"""
@spec document_not_stored(SessionState.t(), binary()) ::
{:error, {:document_already_stored, map()}} | {:ok, map()}
def document_not_stored(%SessionState{} = state, entity_id) do
case Map.get(state.documents_by_id, entity_id) do
nil -> {:ok, entity_id}
document -> {:error, {:document_already_stored, document}}
end
end
@doc """
Return an error if the document is not in the session
"""
@spec document_in_session?(SessionState.t(), any) ::
{:error, :document_not_in_session} | {:ok, map}
def document_in_session?(%SessionState{} = state, entity_id) do
case Map.get(state.documents_by_id, entity_id) do
nil -> {:error, :document_not_in_session}
document -> {:ok, document}
end
end
@doc """
Returns an error if all the informed ids are already loaded in the session
"""
@spec all_ids_are_not_already_loaded(list, list) ::
{:error, :all_ids_already_loaded} | {:ok, [...]}
def all_ids_are_not_already_loaded(document_ids, already_loaded_ids) do
case document_ids -- already_loaded_ids do
[] -> {:error, :all_ids_already_loaded}
ids_to_load -> {:ok, ids_to_load}
end
end
@spec session_request_limit_reached(SessionState.t()) ::
{:error, :max_amount_of_requests_reached} | {:ok, -1}
def session_request_limit_reached(%SessionState{} = state) do
case state.number_of_requests + 1 > state.conventions.max_number_of_requests_per_session do
false -> {:ok, -1}
true -> {:error, :max_amount_of_requests_reached}
end
end
@spec load_documents_limit_reached(SessionState.t(), list) ::
{:error, :max_amount_of_ids_reached} | {:ok, -1}
def load_documents_limit_reached(%SessionState{} = state, document_ids) do
case (Map.keys(state.documents_by_id) |> length) + length(document_ids) >
state.conventions.max_ids_to_catch do
false -> {:ok, -1}
true -> {:error, :max_amount_of_ids_reached}
end
end
end