defmodule Bcs do
@moduledoc """
BCS format.
"""
@doc """
Encode an BCS struct.
"""
@spec encode(value :: struct()) :: {:ok, binary()} | :error
def encode(%module{} = value) do
{:ok, Bcs.Encoder.encode(value, module)}
rescue _ ->
:error
end
@doc """
Same as encode/1, but raises ArgumentError.
"""
@spec encode!(value :: struct()) :: binary()
def encode!(%module{} = value) do
Bcs.Encoder.encode(value, module)
end
@doc """
Encode an BCS value to type.
"""
@spec encode(value :: term(), type :: term()) :: {:ok, binary()} | :error
def encode(value, type) do
{:ok, Bcs.Encoder.encode(value, type)}
rescue _ ->
:error
end
@doc """
Same as encode/2, but raises ArgumentError.
"""
@spec encode!(value :: term(), type :: term()) :: binary()
defdelegate encode!(value, type), to: Bcs.Encoder, as: :encode
@doc """
Decode bytes as BCS type.
"""
@spec decode(bytes :: binary(), type :: term()) :: {:ok, term()} | :error
defdelegate decode(bytes, type), to: Bcs.Decoder
@doc """
Same as decode/2, but raises ArgumentError.
"""
@spec decode!(bytes :: binary(), type :: term()) :: term()
def decode!(bytes, type) do
case Bcs.Decoder.decode(bytes, type) do
{:ok, value} ->
value
:error ->
raise ArgumentError, "Can't decode #{inspect(bytes)} as #{inspect(type)}"
end
end
end