View Source Protox (Protox v1.6.8)
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",
]
endFrom a string:
defmodule Dummy do
use Protox,
schema: """
syntax = "proto3";
package fiz;
message Baz {
}
message Foo {
map<int32, Baz> b = 2;
}
"""
endThe 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;
}
"""
endSee each function documentation to see how they are used to encode and decode protobuf messages.
Link to this section 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.
Errors
This function returns a tuple {:error, reason} if
Throwing version of json_decode/2.
Export a proto3 message to JSON as IO data.
Throwing version of json_encode/1.
Link to this section Functions
Specs
Decode a binary into a protobuf message.
Examples
iex> binary = <<66, 7, 8, 1, 18, 3, 102, 111, 111, 66, 7, 8, 2, 18, 3, 98, 97, 114>>
iex> {:ok, msg} = Protox.decode(binary, Msg)
iex> msg
%Msg{msg_k: %{1 => "foo", 2 => "bar"}}
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, Msg)
iex> reason
%Protox.IllegalTagError{message: "Field with illegal tag 0"}
Specs
Throwing version of decode/2.
Specs
Encode a protobuf message into IO data.
Examples
iex> msg = %Namespace.Fiz.Foo{a: 3, b: %{1 => %Namespace.Fiz.Baz{}}}
iex> {:ok, iodata} = Protox.encode(msg)
iex> :binary.list_to_bin(iodata)
<<8, 3, 18, 4, 8, 1, 18, 0>>
iex> msg = %Namespace.Fiz.Foo{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)"}
Specs
Throwing version of encode/1.
Specs
Errors
This function returns a tuple {:error, reason} if:
inputcould not be decoded to JSON;reasonis aProtox.JsonDecodingErrorerror
JSON library configuration
The default library to decode JSON is Jason.
However, you can chose to use Poison:
iex> Protox.json_decode("{\"a\":\"BAR\"}", Namespace.Fiz.Foo, json_decoder: Poison)
{:ok, %Namespace.Fiz.Foo{__uf__: [], a: :BAR, b: %{}}}You can also use another library as long as it exports an decode! function. You can easily
create a module to wrap a library that would not have this interface (like jiffy):
defmodule Jiffy do
def decode!(input) do
:jiffy.decode(input, [:return_maps, :use_nil])
end
end
Specs
Throwing version of json_decode/2.
Specs
Export a proto3 message to JSON as IO data.
Errors
This function returns a tuple {:error, reason} if:
msgcould not be encoded to JSON;reasonis aProtox.JsonEncodingErrorerror
Examples
iex> msg = %Namespace.Fiz.Foo{a: :BAR}
iex> {:ok, iodata} = Protox.json_encode(msg)
iex> iodata
["{", ["\"a\"", ":", "\"BAR\""], "}"]
iex> msg = %Sub{a: 42}
iex> {:ok, iodata} = Protox.json_encode(msg)
iex> iodata
["{", ["\"a\"", ":", "42"], "}"]
iex> msg = %Msg{msg_k: %{1 => "foo", 2 => "bar"}}
iex> {:ok, iodata} = msg |> Protox.json_encode()
iex> :binary.list_to_bin(iodata)
"{\"msgK\":{\"2\":\"bar\",\"1\":\"foo\"}}"JSON library configuration
The default library to encode values (i.e. mostly to escape strings) to JSON is Jason.
However, you can chose to use Poison:
iex> msg = %Namespace.Fiz.Foo{a: :BAR}
iex> Protox.json_encode(msg, json_encoder: Poison)
{:ok, ["{", ["\"a\"", ":", "\"BAR\""], "}"]}You can also use another library as long as it exports an encode! function, which is expected to return objects as maps and nil
to represent null.
You can easily create a module to wrap a library that would not have this interface (like jiffy):
defmodule Jiffy do
defdelegate encode!(msg), to: :jiffy, as: :encode
endEncoding specifications
See https://developers.google.com/protocol-buffers/docs/proto3#json for the specifications of the encoding.
Specs
Throwing version of json_encode/1.