Skip to content

hayesgm/protobuf-ex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

protobuf-ex

Hex.pm

A pure Elixir implementation of Google Protobuf

Why this instead of exprotobuf(gpb)?

It has some must-have and other cool features like:

  1. A protoc plugin to generate Elixir code just like what other official libs do, which is powerful and reliable.
  2. Generate simple and explicit code with the power of Macro. (see test/support/test_msg.ex)
  3. Plugins support.
  4. Use structs for messages instead of Erlang records.
  5. Support Typespec in generated code.

Installation

The package can be installed by adding protobuf to your list of dependencies in mix.exs:

def deps do
  [{:protobuf_ex, "~> 0.6.1"}]
end

Features

  • Define messages with DSL
  • Decode basic messages
  • Skip unknown fields
  • Decode embedded messages
  • Decode packed and repeated fields
  • Encode messages
  • protoc plugin
  • map
  • Support default values
  • Validate values
  • Generate typespecs
  • Plugins
  • oneof

Usage

Generate Elixir code

  1. Install protoc(cpp) here
  2. Install protoc plugin protoc-gen-elixir for Elixir. NOTE: You have to make sure protoc-gen-elixir(this name is important) is in your PATH.
$ mix escript.install hex protobuf_ex
  1. Generate Elixir code using protoc
$ protoc --elixir_out=./lib helloword.proto
  1. Files helloworld.pb.ex will be generated, like:
defmodule Helloworld.HelloRequest do
  use Protobuf, syntax: :proto3

  @type t :: %__MODULE__{
    name: String.t
  }
  defstruct [:name]

  field :name, 1, type: :string
end

defmodule Helloworld.HelloReply do
  use Protobuf, syntax: :proto3

  @type t :: %__MODULE__{
    message: String.t
  }
  defstruct [:message]

  field :message, 1, type: :string
end

Encode and decode in your code

struct = Foo.new(a: 3.2, c: Foo.Bar.new())
encoded = Foo.encode(struct)
struct = Foo.decode(encoded)

Note:

  • You should use YourModule.new instead of using the struct directly because default values will be set for all fields.
  • Default values will be set by default in decode, which can be changed by :use_default option.
  • Validation is done in encode. An error will be raised if the struct is invalid(like type is not matched).

Tips for protoc

  • Custom protoc-gen-elixir name or path using --plugin
$ protoc --elixir_out=./lib --plugin=./protoc-gen-elixir *.proto
  • Pass -I argument if you import other protobuf files
$ protoc -I protos --elixir_out=./lib protos/hello.proto

Acknowledgements

Many thanks to Tony Han's protobuf-elixir, gpb and golang/protobuf as good examples of writing Protobuf decoder/encoder. This code is maintained as a fork of protobuf-elixir until we can reconcile plugin support.

About

Elixir Protobufs Implementation (Based on https://github.com/tony612/protobuf-elixir)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published