defmodule Stellar.TxBuild.SCError do
@moduledoc """
`ScErrorCode` struct definition.
"""
alias StellarBase.XDR.{SCError, SCErrorType, SCErrorCode}
@behaviour Stellar.TxBuild.XDR
@type code ::
:arith_domain
| :index_bounds
| :invalid_input
| :missing_value
| :existing_value
| :exceeded_limit
| :invalid_action
| :internal_error
| :unexpected_type
| :unexpected_size
@type type ::
:contract
| :wasm_vm
| :context
| :storage
| :object
| :crypto
| :events
| :budget
| :code
| :auth
@type t :: %__MODULE__{type: type(), code: code()}
defstruct [:type, :code]
@types %{
contract: :SCE_CONTRACT,
wasm_vm: :SCE_WASM_VM,
context: :SCE_CONTEXT,
storage: :SCE_STORAGE,
object: :SCE_OBJECT,
crypto: :SCE_CRYPTO,
events: :SCE_EVENTS,
budget: :SCE_BUDGET,
code: :SCE_VALUE,
auth: :SCE_AUTH
}
@codes %{
arith_domain: :SCEC_ARITH_DOMAIN,
index_bounds: :SCEC_INDEX_BOUNDS,
invalid_input: :SCEC_INVALID_INPUT,
missing_value: :SCEC_MISSING_VALUE,
existing_value: :SCEC_EXISTING_VALUE,
exceeded_limit: :SCEC_EXCEEDED_LIMIT,
invalid_action: :SCEC_INVALID_ACTION,
internal_error: :SCEC_INTERNAL_ERROR,
unexpected_type: :SCEC_UNEXPECTED_TYPE,
unexpected_size: :SCEC_UNEXPECTED_SIZE
}
@impl true
def new(args, opts \\ [])
def new([{type, code}], _opts)
when is_map_key(@types, type) and is_map_key(@codes, code) do
%__MODULE__{type: type, code: code}
end
def new(_args, _opts), do: {:error, :invalid_sc_error}
@impl true
def to_xdr(%__MODULE__{type: type, code: code}) do
with {:ok, type} <- retrieve_xdr_type(type),
{:ok, code} <- retrieve_xdr_code(code) do
code = SCErrorCode.new(code)
type
|> SCErrorType.new()
|> SCError.new(code)
end
end
def to_xdr(_struct), do: {:error, :invalid_struct}
defp retrieve_xdr_type(type), do: {:ok, Map.get(@types, type)}
defp retrieve_xdr_code(code), do: {:ok, Map.get(@codes, code)}
end