defmodule Manganese.EntityKit.Structs.EntitiesUpdate do alias Manganese.EntityKit.Protocols alias Manganese.EntityKit.Structs @type t :: %Structs.EntitiesUpdate{ entities: Structs.EntitiesCollection.t, removed_entities: Structs.EntityReferencesCollection.t } defstruct [ entities: Structs.EntitiesCollection.new, removed_entities: Structs.EntityReferencesCollection.new ] # Utilities @doc """ An empty entities update. """ @spec new :: t def new, do: %Structs.EntitiesUpdate{} @doc """ """ @spec put_entity(t, atom, term) :: t def put_entity(entities_update, entity_type, entity) do entities_update |> Map.put( :entities, (entities_update.entities || Structs.EntitiesCollection.new()) |> Structs.EntitiesCollection.put_entity(entity_type, entity) ) end @doc """ """ @spec put_entities(t, atom, [ term ]) :: t def put_entities(entities_update, entity_type, entities) do entities_update |> Map.put( :entities, (entities_update.entities || Structs.EntitiesCollection.new()) |> Structs.EntitiesCollection.put_entities(entity_type, entities) ) end @doc """ """ @spec put_entities_collection(t, Structs.EntitiesCollection.t) :: t def put_entities_collection(entities_update, entities_collection) do entities_update |> Map.put( :entities, (entities_update.entities || Structs.EntitiesCollection.new()) |> Structs.EntitiesCollection.merge(entities_collection) ) end @doc """ """ @spec put_removed_entity_id(t, atom, pos_integer) :: t def put_removed_entity_id(entities_update, entity_type, removed_entity_id) do entities_update |> Map.put( :removed_entities, (entities_update.removed_entities || Structs.EntityReferencesCollection.new) |> Structs.EntityReferencesCollection.put_entity_id(entity_type, removed_entity_id) ) end @doc """ """ @spec put_removed_entity_ids(t, atom, [ pos_integer ]) :: t def put_removed_entity_ids(entities_update, entity_type, removed_entity_ids) do entities_update |> Map.put( :removed_entities, (entities_update.removed_entities || Structs.EntityReferencesCollection.new) |> Structs.EntityReferencesCollection.put_entity_ids(entity_type, removed_entity_ids) ) end @doc """ """ @spec put_removed_entity(t, atom, term) :: t def put_removed_entity(entities_update, entity_type, removed_entity) do entities_update |> put_removed_entity_id(entity_type, removed_entity.id) end @doc """ """ @spec put_removed_entities(t, atom, [ term ]) :: t def put_removed_entities(entities_update, entity_type, removed_entities) do removed_entity_ids = removed_entities |> Enum.map(fn entity -> entity.id end) entities_update |> put_removed_entity_ids(entity_type, removed_entity_ids) end @doc """ """ @spec put_removed_entity_references_collection(t, Structs.EntityReferencesCollection.t) :: t def put_removed_entity_references_collection(entities_update, removed_entity_references_collection) do entities_update |> Map.put( :removed_entities, (entities_update.removed_entities || Structs.EntityReferencesCollection.new) |> Structs.EntityReferencesCollection.merge(removed_entity_references_collection) ) end @doc """ """ @spec merge(t, t) :: t def merge(entities_update1, entities_update2) do new() |> put_entities_collection( Structs.EntitiesCollection.merge( entities_update1.entities, entities_update2.entities ) ) |> put_removed_entity_references_collection( Structs.EntityReferencesCollection.merge( entities_update1.removed_entities, entities_update2.removed_entities ) ) end end defimpl Manganese.EntityKit.Protocols.Filterable, for: Manganese.EntityKit.Structs.EntitiesUpdate do alias Manganese.EntityKit.Protocols alias Manganese.EntityKit.Structs def filter(entities_update, filter) do %Structs.EntitiesUpdate{ entities: entities_update.entities |> Protocols.Filterable.filter(filter), removed_entities: entities_update.removed_entities |> Protocols.Filterable.filter(filter) } end end defimpl Manganese.EntityKit.Protocols.Serializable, for: Manganese.EntityKit.Structs.EntitiesUpdate do alias Manganese.EntityKit.Protocols alias Manganese.EntityKit.Structs def serialize(entities_update, serializer) do %{ "entities" => entities_update.entities |> Protocols.Serializable.serialize(serializer), "removed_entities" => entities_update.removed_entities |> Structs.EntityReferencesCollection.to_map } end end defimpl Manganese.EntityKit.Protocols.Reloadable, for: Manganese.EntityKit.Structs.EntitiesUpdate do alias Manganese.EntityKit.Protocols alias Manganese.EntityKit.Structs def reload(entities_update, repo) do %Structs.EntitiesUpdate{ entities: entities_update.entities |> Protocols.Reloadable.reload(repo), removed_entities: entities_update.removed_entities } end end