defmodule LiveViewNativePlatform.Modifier do
@moduledoc """
Supporting functionality and macros for modifiers.
"""
defmacro __using__(_) do
quote do
import LiveViewNativePlatform.Modifier,
only: [
modifier_schema: 1,
modifier_schema: 2,
change_event: 0
]
end
end
@doc """
Generates a field for storing modifier events triggered with `phx-change`.
"""
defmacro change_event do
quote do
field(:change, LiveViewNativePlatform.Modifier.Types.Event, default: nil)
end
end
@doc """
Defines a modifier schema that takes no parameters.
"""
defmacro modifier_schema(modifier_name) do
quote do
modifier_schema(unquote(modifier_name), do: {:__block__, [], []})
end
end
@doc """
Defines a modifier schema.
"""
defmacro modifier_schema(modifier_name, do: block) do
quote do
use Ecto.Schema
import Ecto.Changeset
@primary_key false
@derive Jason.Encoder
schema(unquote(modifier_name)) do
unquote(block)
end
def __lvn_modifier__, do: %{
modifier_name: unquote(modifier_name)
}
def changeset(modifier \\ %__MODULE__{}, attrs) do
modifier
|> cast(attrs, fields(), empty_values: [])
end
def fields do
__schema__(:fields)
end
def modifier(modifier \\ %__MODULE__{}, attrs)
def modifier(modifier, attrs) when is_map(attrs) do
modifier
|> changeset(attrs)
|> Ecto.Changeset.apply_changes()
end
def modifier(modifier, attrs) when is_list(attrs) do
modifier(modifier, Enum.into(attrs, %{}))
end
def modifier_name do
__schema__(:source)
end
def to_map(modifier \\ %__MODULE__{}) do
modifier
|> Map.from_struct()
|> Map.delete(:__meta__)
end
end
end
end