Current section

Files

Jump to
manganese_entity_kit lib structs entity_references_collection.ex
Raw

lib/structs/entity_references_collection.ex

defmodule Manganese.EntityKit.Structs.EntityReferencesCollection do
alias Manganese.EntityKit.Structs
alias Manganese.EntityKit.Behaviors
@type t :: %Structs.EntityReferencesCollection{
entity_ids: %{ optional(atom) => [ Behaviors.Entity.id ] }
}
defstruct [
entity_ids: %{}
]
# Utilities
@doc """
"""
@spec new :: t
def new, do: %Structs.EntityReferencesCollection{}
@doc """
Check if an entity of the given type and ID are referenced in the collection.
"""
@spec has_entity?(t, atom, pos_integer) :: t
def has_entity?(entity_references_collection, entity_type, id) do
Enum.member?(
Map.get(entity_references_collection.entity_ids, entity_type, []),
id
)
end
@doc """
Add an entity reference to the collection.
"""
@spec put_entity_id(t, atom, pos_integer) :: t
def put_entity_id(entity_references_collection, entity_type, id) do
%Structs.EntityReferencesCollection{
entity_ids:
entity_references_collection.entity_ids
|> Map.put(
entity_type,
((Map.get(entity_references_collection.entity_ids, entity_type) || []) ++ [ id ])
|> Enum.uniq
)
}
end
@doc """
Add multiple entity references to the collection.
"""
@spec put_entity_ids(t, atom, [ pos_integer ]) :: t
def put_entity_ids(entity_references_collection, entity_type, ids) do
%Structs.EntityReferencesCollection{
entity_ids:
entity_references_collection.entity_ids
|> Map.put(
entity_type,
((Map.get(entity_references_collection.entity_ids, entity_type) || []) ++ ids)
|> Enum.uniq
)
}
end
@doc """
"""
@spec merge(t, t) :: t
def merge(entity_references_collection1, entity_references_collection2) do
%Structs.EntityReferencesCollection{
entity_ids: Map.merge(
(entity_references_collection1 || %Structs.EntityReferencesCollection{}).entity_ids,
(entity_references_collection2 || %Structs.EntityReferencesCollection{}).entity_ids,
fn _entity_type, entity_ids1, entity_ids2 ->
((entity_ids1 || []) ++ (entity_ids2 || []))
|> Enum.uniq
end
)
}
end
@doc """
"""
@spec filter(t, (atom, Behaviors.Entity.id -> boolean)) :: map
def filter(entity_references_collection, filter) do
end
@doc """
"""
@spec to_map(t) :: map
def to_map(entity_references_collection) do
entity_references_collection.entity_ids
|> Map.new(fn { entity_type, entity_ids_of_type } ->
{ Atom.to_string(entity_type), entity_ids_of_type }
end)
end
end
defimpl Manganese.EntityKit.Protocols.Filterable, for: Manganese.EntityKit.Structs.EntityReferencesCollection do
alias Manganese.EntityKit.Protocols
alias Manganese.EntityKit.Structs
def filter(entity_references_collection, filter) do
%Structs.EntityReferencesCollection{
entity_ids:
entity_references_collection.entity_ids
|> Map.new(fn { entity_type, entity_ids_of_type } ->
{
entity_type,
entity_ids_of_type
|> Enum.filter(fn entity_id ->
filter.(entity_type, entity_id)
end)
}
end)
|> Enum.filter(fn { _, entity_ids_of_type } ->
!(is_nil(entity_ids_of_type) || (is_list(entity_ids_of_type) && length(entity_ids_of_type) == 0))
end)
|> Enum.into(%{})
}
end
end