defmodule Ash.Type.Struct do @moduledoc """ Represents a struct. This cannot be loaded from a database, it can only be used to cast input. Use the `instance_of` constraint to specify that it must be an instance of a specific struct. """ use Ash.Type @constraints [ instance_of: [ type: :atom, doc: "The module the struct should be an instance of" ] ] @impl true def constraints, do: @constraints @impl true def storage_type, do: :map @impl true def cast_input(nil, _), do: {:ok, nil} def cast_input(%struct{} = value, constraints) do case constraints[:instance_of] do nil -> {:ok, value} ^struct -> {:ok, value} _ -> :error end end def cast_input(_, _), do: :error @impl Ash.Type def load(record, load, _constraints, %{api: api} = context) do opts = context |> Map.take([:actor, :authorize?, :tenant, :tracer]) |> Map.to_list() api.load(record, load, opts) end @impl Ash.Type def can_load?(constraints) do constraints[:instance_of] && Ash.Resource.Info.resource?(constraints[:instance_of]) end @impl true def cast_stored(_, _), do: :error @impl true def dump_to_native(_, _), do: :error end