Skip to content

Union example

Francisco Molina edited this page May 25, 2020 · 3 revisions

Statement

defmodule XDR.Statement do
  @behaviour XDR.Declaration

  defstruct declarations: nil, identifier: nil

  @statement_type [
    ST_PREPARE: 0,
    ST_CONFIRM: 1,
    ST_EXTERNALIZE: 2,
    ST_NOMINATE: 3
  ]

  def new(identifier),
    do: %XDR.Statement{declarations: @statement_type, identifier: identifier}

  @impl XDR.Declaration
  defdelegate encode_xdr(enum), to: XDR.Enum

  @impl XDR.Declaration
  defdelegate encode_xdr!(enum), to: XDR.Enum

  @impl XDR.Declaration
  def decode_xdr(bytes, struct \\  %{declarations: @statement_type})
  def decode_xdr(bytes, struct) do
    {%{identifier: identifier}, rest} = XDR.Enum.decode_xdr!(bytes, struct)
    {:ok, {new(identifier), rest}}
  end

  @impl XDR.Declaration
  def decode_xdr!(bytes, struct \\  %{declarations: @statement_type})
  def decode_xdr!(bytes, struct), do: decode_xdr(bytes, struct) |> elem(1)
end

UnionStatement

defmodule XDR.UnionStatementdo
  @behaviour XDR.Declaration
  alias XDR.Statement

  defstruct discriminant: XDR.Enum, arms: nil

  @arms [
    ST_PREPARE: XDR.Int.new(60),
    ST_CONFIRM: XDR.String.new("Confirm"),
    ST_EXTERNALIZE: XDR.Bool.new(false),
    ST_NOMINATE: XDR.Float.new(3.46)
  ]

  @spec new(any) :: XDR.UnionStatement.t()
  def new(identifier),
    do: %XDR.UnionStatementType{
      discriminant: StatementType.new(identifier),
      arms: @arms,
      struct: %{discriminant: XDR.Enum}
    }

  @impl XDR.Declaration
  def encode_xdr(%XDR.UnionStatement{} = union), do: XDR.Union.encode_xdr(union)

  @impl XDR.Declaration
  def encode_xdr!(%XDR.UnionStatement{} = union), do: encode_xdr(union) |> elem(1)

  @impl XDR.Declaration
  def decode_xdr(bytes, union \\ new(nil))
  def decode_xdr(bytes, %XDR.UnionStatement{} = union) do
    XDR.Union.decode_xdr(bytes, union)
  end

  @impl XDR.Declaration
  def decode_xdr!(bytes, union \\ new(nil))
  def decode_xdr!(bytes, %XDR.UnionStatement{} = union) do
    XDR.Union.decode_xdr!(bytes, union)
  end
end

Union

iex(1)> XDR.UnionStatement.new(:ST_NOMINATE) |> XDR.UnionStatement.encode_xdr()
{:ok, <<0, 0, 0, 3, 64, 93, 112, 164>>}

iex(3)> XDR.UnionStatement.decode_xdr(<<0, 0, 0, 3, 64, 93, 112, 164>>)
{:ok, {{:ST_NOMINATE, %XDR.Float{float: 3.4600000381469727}}, ""}}
Clone this wiki locally