defmodule Kadena.Types.Signer do
@moduledoc """
`Signer` struct definition.
"""
alias Kadena.Types.{Base16String, Cap}
@behaviour Kadena.Types.Spec
@type pub_key :: Base16String.t()
@type scheme :: :ed25519 | nil
@type addr :: Base16String.t() | nil
@type clist :: list(Cap.t()) | nil
@type value :: pub_key() | scheme() | addr() | clist()
@type str :: String.t()
@type validation :: {:ok, value()} | {:error, Keyword.t()}
@type t :: %__MODULE__{
pub_key: pub_key(),
scheme: scheme(),
addr: addr(),
clist: clist()
}
defstruct [:pub_key, :scheme, :addr, :clist]
@impl true
def new(args) do
pub_key = Keyword.get(args, :pub_key)
scheme = Keyword.get(args, :scheme)
addr = Keyword.get(args, :addr)
clist = Keyword.get(args, :clist)
with {:ok, pub_key} <- validate_pub_key(pub_key),
{:ok, scheme} <- validate_scheme(scheme),
{:ok, addr} <- validate_addr(addr),
{:ok, clist} <- validate_clist(clist) do
%__MODULE__{pub_key: pub_key, scheme: scheme, addr: addr, clist: clist}
end
end
@spec validate_pub_key(pub_key :: str()) :: validation()
defp validate_pub_key(pub_key) when is_binary(pub_key), do: {:ok, Base16String.new(pub_key)}
defp validate_pub_key(_pub_key), do: {:error, [pub_key: :invalid]}
@spec validate_scheme(scheme :: scheme()) :: validation()
defp validate_scheme(nil), do: {:ok, nil}
defp validate_scheme(:ed25519), do: {:ok, :ed25519}
defp validate_scheme(_code), do: {:error, [scheme: :invalid]}
@spec validate_addr(addr :: str() | nil) :: validation()
defp validate_addr(nil), do: {:ok, nil}
defp validate_addr(addr) when is_binary(addr), do: {:ok, Base16String.new(addr)}
defp validate_addr(_addr), do: {:error, [addr: :invalid]}
@spec validate_clist(clist :: clist()) :: validation()
defp validate_clist(nil), do: {:ok, nil}
defp validate_clist([%Cap{} | _tail] = clist), do: {:ok, clist}
defp validate_clist(_clist), do: {:error, [clist: :not_a_caps_list]}
end