defmodule Kadena.Types.SignedCommand do @moduledoc """ `SignedCommand` struct definition. """ alias Kadena.Types.Signature @behaviour Kadena.Types.Spec @type str :: String.t() @type hash :: str() @type cmd :: str() @type sigs :: list(Signature.t()) @type value :: str() | sigs() @type validation :: {:ok, value()} | {:error, Keyword.t()} @type t :: %__MODULE__{ hash: hash(), sigs: sigs(), cmd: cmd() } defstruct [:hash, :sigs, :cmd] @impl true def new(args) do hash = Keyword.get(args, :hash) sigs = Keyword.get(args, :sigs) cmd = Keyword.get(args, :cmd) with {:ok, hash} <- validate_str(:hash, hash), {:ok, cmd} <- validate_str(:cmd, cmd), {:ok, sigs} <- validate_sigs(sigs) do %__MODULE__{hash: hash, sigs: sigs, cmd: cmd} end end @spec validate_str(field :: atom(), value :: str()) :: validation() defp validate_str(_field, value) when is_binary(value), do: {:ok, value} defp validate_str(field, _value), do: {:error, [{field, :invalid}]} @spec validate_sigs(sigs :: sigs()) :: validation() defp validate_sigs([%Signature{} | _tail] = sigs), do: {:ok, sigs} defp validate_sigs(_sigs), do: {:error, [sigs: :invalid]} end