Protox (Protox v2.0.4)

View Source

Use this module to generate the Elixir structs corresponding to a set of protobuf definitions and to encode/decode instances of these structures.

Elixit structs generation examples

From a set of files:

defmodule Dummy do
  use Protox,
    files: [
      "./defs/foo.proto",
      "./defs/bar.proto",
      "./defs/baz/fiz.proto",
    ]
end

From a string:

defmodule Dummy do
  use Protox,
    schema: """
    syntax = "proto3";
    package fiz;

    message Baz {
    }

    message Foo {
      map<int32, Baz> b = 2;
    }
    """
end

The generated modules respect the package declaration. For instance, in the above example, both the Fiz.Baz and Fiz.Foo modules will be generated.

Encoding/decoding

For the rest of this module documentation, we suppose the following protobuf messages are defined:

defmodule Dummy do
  use Protox,
    schema: """
      syntax = "proto3";
      package fiz;

      message Baz {
      }

      enum Enum {
        FOO = 0;
        BAR = 1;
      }

      message Foo {
        Enum a = 1;
        map<int32, Baz> b = 2;
      }
    """,
    namespace: Namespace

  use Protox,
    schema: """
    syntax = "proto3";

    message Msg {
      map<int32, string> msg_k = 8;
    }
    """

  use Protox,
    schema: """
    syntax = "proto3";

    message Sub {
      int32 a = 1;
    }
    """
end

See each function documentation to see how they are used to encode and decode protobuf messages.

Summary

Functions

Decode a binary into a protobuf message.

Throwing version of decode/2.

Encode a protobuf message into IO data.

Throwing version of encode/1.

Functions

decode(binary, msg_module)

(since 1.6.0)
@spec decode(binary(), atom()) :: {:ok, struct()} | {:error, any()}

Decode a binary into a protobuf message.

Examples

iex> binary = <<8, 42, 18, 7, 8, 1, 18, 3, 102, 111, 111>>
iex> {:ok, msg} = Protox.decode(binary, ProtoxExample)
iex> msg
%ProtoxExample{a: 42, b: %{1 => "foo"}}

iex> binary = <<66, 7, 8, 1, 18, 3, 102, 111, 66, 7, 8, 2, 18, 3, 98, 97, 114>>
iex> {:error, reason} = Protox.decode(binary, ProtoxExample)
iex> reason
%Protox.DecodingError{
              message: "Could not decode data (invalid wire type 7)",
              binary: <<7, 8, 2, 18, 3, 98, 97, 114>>
            }

decode!(binary, msg_module)

(since 1.6.0)
@spec decode!(binary(), atom()) :: struct() | no_return()

Throwing version of decode/2.

encode(msg)

(since 1.6.0)
@spec encode(struct()) :: {:ok, iodata(), non_neg_integer()} | {:error, any()}

Encode a protobuf message into IO data.

Examples

iex> msg = %ProtoxExample{a: 3, b: %{1 => "some string"}}
iex> {:ok, iodata, _iodata_size} = Protox.encode(msg)
iex> IO.iodata_to_binary(iodata)
<<8, 3, 18, 15, 8, 1, 18, 11, 115, 111, 109, 101, 32, 115, 116, 114, 105, 110, 103>>

iex> msg = %ProtoxExample{a: "should not be a string"}
iex> {:error, reason} = Protox.encode(msg)
iex> reason
%Protox.EncodingError{field: :a, message: "Could not encode field :a (invalid field value)"}

encode!(msg)

(since 1.6.0)
@spec encode!(struct()) :: {iodata(), non_neg_integer()} | no_return()

Throwing version of encode/1.