defmodule Kadena.Types.ExecPayload do
@moduledoc """
`ExecPayload` struct definition.
"""
alias Kadena.Types.{EnvData, PactCode}
@behaviour Kadena.Types.Spec
@type data :: EnvData.t() | nil
@type code :: PactCode.t()
@type value :: data() | code()
@type validation :: {:ok, value()} | {:error, Keyword.t()}
@type t :: %__MODULE__{
data: data(),
code: code()
}
defstruct [:data, :code]
@impl true
def new(args) do
data = Keyword.get(args, :data)
code = Keyword.get(args, :code)
with {:ok, data} <- validate_data(data),
{:ok, code} <- validate_code(code) do
%__MODULE__{data: data, code: code}
end
end
@spec validate_data(data :: map()) :: validation()
defp validate_data(nil), do: {:ok, nil}
defp validate_data(%EnvData{} = data), do: {:ok, data}
defp validate_data(data) do
case EnvData.new(data) do
%EnvData{} = data -> {:ok, data}
_error -> {:error, [data: :invalid]}
end
end
@spec validate_code(code :: String.t()) :: validation()
defp validate_code(code) do
case PactCode.new(code) do
%PactCode{} = code -> {:ok, code}
_error -> {:error, [code: :invalid]}
end
end
end