defmodule Spear.StreamMetadata do
@moduledoc """
A struct for describing the metadata about a stream
"""
@reserved_keys ~w[$maxAge $tb $cacheControl $maxCount $acl]
@typedoc """
Internal and custom metadata about a stream
See the EventStoreDB stream metadata documentation for more details.
"""
@typedoc since: "0.1.3"
@type t :: %__MODULE__{
max_age: pos_integer() | nil,
truncate_before: pos_integer() | nil,
cache_control: pos_integer() | nil,
max_count: pos_integer() | nil,
acl: Spear.Acl.t() | nil,
custom: %{String.t() => any()} | nil
}
defstruct [:max_age, :truncate_before, :cache_control, :max_count, :acl, :custom]
@doc """
Converts a stream metadata struct to a map in the format EventStoreDB expects
"""
def to_map(%__MODULE__{} = metadata) do
%{
"$maxAge" => metadata.max_age,
"$tb" => metadata.truncate_before,
"$cacheControl" => metadata.cache_control,
"$maxCount" => metadata.max_count,
"$acl" => metadata.acl && Spear.Acl.to_map(metadata.acl)
}
|> Map.merge(metadata.custom || %{})
|> Enum.reject(fn {_k, v} -> v in [nil, %{}] end)
|> Enum.into(%{})
end
@doc false
def from_spear_event(%Spear.Event{type: "$metadata"} = event) do
%__MODULE__{
max_age: Map.get(event.body, "$maxAge"),
truncate_before: Map.get(event.body, "$tb"),
cache_control: Map.get(event.body, "$cacheControl"),
max_count: Map.get(event.body, "$cacheControl"),
acl: Map.get(event.body, "$acl", %{}) |> Spear.Acl.from_map(),
custom: Map.drop(event.body, @reserved_keys)
}
end
end