Current section
Files
Jump to
Current section
Files
lib/transaction/response.ex
defmodule Xander.Transaction.Response do
@moduledoc """
Parses the response from a transaction. Accepts CBOR encoded responses.
"""
require Logger
@type error_reason ::
:cannot_decode_non_binary_values
| :cbor_function_clause_error
| :cbor_match_error
| :invalid_format
| :invalid_input
| :disconnected
@type t :: {:ok, :accepted} | {:rejected, any()} | {:error, error_reason}
@doc """
Parses the response from a transaction. Accepts CBOR encoded responses.
## Examples
# Transaction accepted
iex> binary = Xander.Util.plex_encode(CBOR.encode([1]))
iex> Xander.Transaction.Response.parse_response(binary)
{:ok, :accepted}
# Transaction rejected with reason
iex> tag = %CBOR.Tag{tag: :bytes, value: "invalid tx"}
iex> binary = Xander.Util.plex_encode(CBOR.encode([2, tag]))
iex> Xander.Transaction.Response.parse_response(binary)
{:rejected, %CBOR.Tag{tag: :bytes, value: "invalid tx"}}
# Disconnected from node
iex> binary = Xander.Util.plex_encode(CBOR.encode([3]))
iex> Xander.Transaction.Response.parse_response(binary)
{:error, :disconnected}
# Error handling invalid CBOR
iex> Xander.Transaction.Response.parse_response(<<0, 1, 2, 3>>)
{:error, :invalid_format}
# Error handling nil input
iex> Xander.Transaction.Response.parse_response(nil)
{:error, :invalid_input}
"""
@spec parse_response(binary() | nil) :: t()
def parse_response(cbor_response) do
case Xander.Util.plex(cbor_response) do
{:ok, %{payload: cbor_response_payload}} ->
decode(cbor_response_payload)
{:error, reason} ->
{:error, reason}
end
end
defp decode(cbor_response_payload) do
case CBOR.decode(cbor_response_payload) do
{:ok, [1], <<>>} ->
{:ok, :accepted}
{:ok, [2, failure_reason], <<>>} ->
{:rejected, failure_reason}
{:ok, [3], <<>>} ->
{:error, :disconnected}
{:error, error} ->
{:error, error}
end
end
end