defmodule Stellar.TxBuild.Ledger.ContractCode do @moduledoc """ `ContractCode` struct definition. """ alias StellarBase.XDR.{ContractEntryBodyType, Hash, LedgerKeyContractCode} @behaviour Stellar.TxBuild.XDR @type error :: {:error, atom()} @type validation :: {:ok, any()} | error() @type hash :: String.t() @type body_type :: :data_entry | :expiration_ext @type t :: %__MODULE__{ hash: hash(), body_type: body_type() } defstruct [:hash, :body_type] @allowed_body_types ~w(data_entry expiration_ext)a @impl true def new(args, opts \\ []) def new( [ {:hash, hash}, {:body_type, body_type} ], _opts ) when is_binary(hash) and body_type in @allowed_body_types do %__MODULE__{ hash: hash, body_type: body_type } end def new(_value, _opts), do: {:error, :invalid_ledger_key_args} @impl true def to_xdr(%__MODULE__{ hash: hash, body_type: body_type }) do body_type = body_type_to_xdr(body_type) hash |> Hash.new() |> LedgerKeyContractCode.new(body_type) end def to_xdr(_struct), do: {:error, :invalid_struct} @spec body_type_to_xdr(atom()) :: ContractEntryBodyType.t() defp body_type_to_xdr(:data_entry), do: ContractEntryBodyType.new(:DATA_ENTRY) defp body_type_to_xdr(:expiration_ext), do: ContractEntryBodyType.new(:EXPIRATION_EXTENSION) end