### Install Dependencies Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Fetch and install project dependencies. ```bash mix deps.get ``` -------------------------------- ### Install Git Hooks with Lefthook Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Optionally install Lefthook to enable pre-commit and pre-push checks, ensuring code quality and consistency before committing. ```bash lefthook install ``` -------------------------------- ### Install Protox Dependency in Mix Project Source: https://github.com/ahamez/protox/blob/master/README.md Add the Protox library to your project's dependencies in `mix.exs` to use it. ```elixir def deps do [{:protox, "~> 2.0"}] end ``` -------------------------------- ### Define Protobuf Message and Encode/Decode in Elixir Source: https://github.com/ahamez/protox/blob/master/README.md Example demonstrating how to define a Protobuf message and then encode and decode it using Protox in Elixir. Requires the `Msg` struct to be generated from a proto definition. ```elixir iex> msg = %Msg{a: 42, b: %{1 => "a map entry"}} iex> {:ok, iodata, iodata_size} = Msg.encode(msg) iex> binary = # read binary from a socket, a file, etc. iex> {:ok, msg} = Msg.decode(binary) ``` -------------------------------- ### Get Message Schema Definition Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Returns the underlying message schema definition, including syntax, required fields, and field types. ```elixir @spec schema() :: Protox.MessageSchema.t() schema() ``` -------------------------------- ### Get All Enum Constants Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Returns a list of all constants within an enum, represented as tuples of integer value and atom entry. ```elixir @spec constants() :: [{integer(), atom()}] constants() ``` -------------------------------- ### Get Enum Default Value Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Retrieves the default value for an enum. This is typically an atom representing the default enum entry. ```elixir @spec default() :: atom() default() ``` -------------------------------- ### Get Unknown Fields from Message Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Retrieves unknown fields encountered during decoding. The format is a list of tuples containing field number, tag, and binary data. ```elixir @spec unknown_fields(struct() :: [{non_neg_integer(), Protox.Types.tag(), binary()}]) unknown_fields(msg) ``` -------------------------------- ### Get Name of Unknown Fields Storage Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Returns the atom name of the field used to store unknown fields within a message struct. ```elixir @spec unknown_fields_name() :: atom() unknown_fields_name(msg) ``` -------------------------------- ### Get Message Field Default Value Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Retrieves the default value for a specified message field name. Default values are mandated by Protobuf 3 specifications. ```elixir @spec default(atom() :: {:ok, boolean() | integer() | String.t() | binary() | float()} | {:error, atom()}) default(field_name) ``` -------------------------------- ### Launch Protox Benchmark Source: https://github.com/ahamez/protox/blob/master/benchmark/launch_benchmark.md Use this command to initiate a benchmark run. You can specify the task (encode/decode), control run durations with flags like `--warmup`, `--time`, `--memory-time`, and `--reduction-time`, and must provide a benchmark tag for identification. Results are stored in `./benchmark/output/benchee/`. ```bash mix protox.benchmark.run [--task ] [--warmup 2] [--time 5] [--memory-time 2] [--reduction-time 2] ``` ```bash # Short run (defaults) mix protox.benchmark.run --task decode my_tag ``` ```bash # Longer run to reduce variance mix protox.benchmark.run --task encode --warmup 3 --time 15 --memory-time 5 --reduction-time 5 my_long_tag ``` -------------------------------- ### Run Unit Tests Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Execute the unit test suite. Use the `--include conformance` flag to also run the conformance test suite. ```bash mix test ``` ```bash mix test --include conformance ``` -------------------------------- ### Run Protox Conformance Suite Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Execute the conformance test suite for Protox. Ensure PROTOBUF_VERSION is set if needed, especially in CI environments. ```bash mix protox.conformance ``` -------------------------------- ### Generate Documentation Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Generate user-facing documentation for the project. ```bash mix docs ``` -------------------------------- ### Format Code Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Apply code formatting according to the project's configuration. ```bash mix format ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Generate a code coverage report for the test suite. ```bash mix test --cover ``` -------------------------------- ### Specify Include Paths for Protobuf Files Source: https://github.com/ahamez/protox/blob/master/README.md Configures Protox to search for imported protobuf files in specified directories using the `:paths` option, similar to protoc's `-I` flag. ```elixir defmodule Baz do use Protox, files: [ "./defs1/prefix/foo.proto", "./defs1/prefix/bar.proto", "./defs2/prefix/baz/baz.proto" ], paths: [ "./defs1", "./defs2" ] end ``` -------------------------------- ### Generate Protocol Buffers with Protox Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Use this command to generate Elixir modules from .proto files. Specify the output path and include paths as needed. ```bash mix protox.generate --output-path=lib/messages.ex --include-path=. defs/foo.proto ``` -------------------------------- ### Run Credo Linting Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Perform static analysis and linting using Credo to check for code style and potential issues. ```bash mix credo ``` -------------------------------- ### Aggregate Benchmark Results Source: https://github.com/ahamez/protox/blob/master/benchmark/launch_benchmark.md This command aggregates benchmark results from specified paths. Use wildcards to include multiple result files. ```bash mix protox.benchmark.report ``` ```bash mix protox.benchmark.report ./benchmark/output/benchee/encode-* ``` -------------------------------- ### Compile with Warnings as Errors Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Compile the project and treat all compilation warnings as errors to ensure code quality. ```bash mix compile --warnings-as-errors ``` -------------------------------- ### Generate Elixir Files with Protox Mix Task Source: https://github.com/ahamez/protox/blob/master/README.md Use the `protox.generate` mix task to create Elixir source code files from .proto definitions. Specify the output path and the input .proto files. Protox runtime functions are used in the generated files. ```shell protox.generate --output-path=/path/to/messages.ex protos/foo.proto protos/bar.proto ``` -------------------------------- ### Run Dialyzer Static Analysis Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Perform static analysis using Dialyzer to detect type inconsistencies and potential runtime errors. ```bash mix dialyzer ``` -------------------------------- ### Use Protox with Namespace Option Source: https://github.com/ahamez/protox/blob/master/README.md Generates Elixir modules with a prepended namespace by using the `namespace` option with `Protox`. The generated module name will be `Bar.Abc.Msg` in this case. ```elixir defmodule Bar do use Protox, schema: """ syntax = "proto3"; package abc; message Msg { int32 a = 1; } """, namespace: __MODULE__ end # Example usage: # msg = %Bar.Abc.Msg{a: 42} ``` -------------------------------- ### Check Formatted Code Source: https://github.com/ahamez/protox/blob/master/AGENTS.md Verify that all code adheres to the project's formatting standards using `mix format --check-formatted`. ```bash mix format --check-formatted ``` -------------------------------- ### Use Protox with Multiple Proto Files in Elixir Source: https://github.com/ahamez/protox/blob/master/README.md Configures Protox to generate Elixir modules from multiple protobuf definition files specified in a list. ```elixir defmodule MyModule do use Protox, files: [ "./defs/foo.proto", "./defs/bar.proto", "./defs/baz/fiz.proto" ] end ``` -------------------------------- ### Handle Default Values in Protobuf 3 Source: https://github.com/ahamez/protox/blob/master/README.md Details how unset fields in Protobuf 3 are assigned their default values (e.g., 0 for int32). If the `optional` keyword is used (protoc >= 3.15), unset fields are assigned `nil` and `default/1` may return an error. ```elixir defmodule Bar do use Protox, schema: """ syntax = "proto3"; message Foo { int32 a = 1; optional int32 b = 2; } """ end iex> %Foo{}.a 0 iex> Foo.default(:a) {:ok, 0} iex> %Foo{}.b nil iex> Foo.default(:b) {:error, :no_default_value} ``` -------------------------------- ### Handle Enum Aliases in Protobuf Source: https://github.com/ahamez/protox/blob/master/README.md Shows how Protobuf handles enum aliases when `allow_alias` is true. During decoding, the last encountered constant for a given value is used. Ensure consistent aliasing if needed. ```protobuf enum E { option allow_alias = true; FOO = 0; BAZ = 1; BAR = 1; } ``` -------------------------------- ### Message and Enum Name Conversion Source: https://github.com/ahamez/protox/blob/master/README.md Illustrates how Protox converts message and enum names using `Macro.camelize/1`. Note that field names are not converted. ```elixir defmodule Bar do use Protox, schema: """ syntax = "proto3"; message non_camel_message { } message CamelMessage { int32 non_camel_field = 1; } """ end iex> msg = %NonCamelMessage{} %NonCamelMessage{__uf__: []} iex> msg = %CamelMessage{} %CamelMessage{__uf__: [], non_camel_field: 0} ``` -------------------------------- ### Decode Message Using Generated Structs Source: https://github.com/ahamez/protox/blob/master/README.md Shows how to call `decode/1` and `decode!/1` directly on the Elixir modules generated by Protox to decode a binary protobuf message. ```elixir {:ok, msg} = Foo.decode(<<8, 3, 18, 4, 8, 1, 18, 0>>) msg = Foo.decode!(<<8, 3, 18, 4, 8, 1, 18, 0>>) ``` -------------------------------- ### Encode Protobuf Message (Throwing) Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md A throwing version of the encode/1 function. It returns iodata directly or raises an error. ```elixir @spec encode!(struct() :: iodata() | no_return()) encode!(msg) ``` -------------------------------- ### Encode Message Using Generated Structs Source: https://github.com/ahamez/protox/blob/master/README.md Demonstrates calling `encode/1` and `encode!/1` directly on the Elixir modules generated by Protox, passing the message struct. ```elixir {:ok, iodata, iodata_size} = Foo.encode(msg) {iodata, iodata_size} = Foo.encode!(msg) ``` -------------------------------- ### Protobuf 2 Nested Extensions Field Naming Source: https://github.com/ahamez/protox/blob/master/README.md Illustrates how field names from nested extensions in Protobuf 2 are prefixed with the extender's name to avoid naming conflicts. This ensures unique identification of fields originating from different extensions. ```protobuf message Extendee { extensions 100 to max; } message Extension1 { extend Extendee { optional Extension1 ext1 = 102; } } message Extension2 { extend Extendee { optional int32 ext2 = 103; } } message Extension3 { extend Extendee { optional int32 identical_name = 105; } } message Extension4 { extend Extendee { repeated int32 identical_name = 106; } } ``` ```elixir :extension1_ext1 :extension2_ext2 :extension3_identical_name :extension4_identical_name ``` -------------------------------- ### Message Encoding Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Encodes a message struct into an iodata format suitable for files or sockets. Returns {:ok, iodata} on success or {:error, description} on failure. ```APIDOC ## Message Encoding ### Description Encodes `msg` into an `iodata` suitable for files or sockets. Returns `{:ok, iodata}` when the encoding was successful and `{:error, description}` in case of an encoding error. ### Function Signature ```elixir @spec encode(struct() :: {:ok, iodata()} | {:error, any()}) encode(msg) ``` ### Throwing Version ### Description Throwing version of `encode/1`. ### Function Signature ```elixir @spec encode!(struct() :: iodata() | no_return()) encode!(msg) ``` ``` -------------------------------- ### Decode Protobuf Data (Throwing) Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md A throwing version of the decode/1 function. It returns the decoded struct directly or raises an error. ```elixir @spec decode!(binary() :: struct() | no_return()) decode!(data) ``` -------------------------------- ### Use Protox with Inlined Schema in Elixir Source: https://github.com/ahamez/protox/blob/master/README.md Defines Elixir modules (`Baz`, `Foo`) by embedding a protobuf schema directly within the `Protox` macro. The module name where `Protox` is called is ignored for generated modules. ```elixir defmodule MyModule do use Protox, schema: """ syntax = "proto3"; message Baz { } message Foo { int32 a = 1; map b = 2; } """ end ``` -------------------------------- ### Handle Required Fields Error in Protobuf 2 Source: https://github.com/ahamez/protox/blob/master/README.md Demonstrates how Protox raises a RequiredFieldsError when a required field is missing in Protobuf 2. Ensure all required fields are set before encoding. ```elixir defmodule Bar do use Protox, schema: """ syntax = "proto2"; message Required { required int32 a = 1; } """ end iex> Protox.encode!(%Required{}) ** (Protox.RequiredFieldsError) Some required fields are not set: [:a] ``` -------------------------------- ### Handle Unset Optional Fields in Protobuf 2 Source: https://github.com/ahamez/protox/blob/master/README.md Explains that unset optional fields in Protobuf 2 are assigned `nil`. The generated `default/1` function can be used to retrieve the default value defined in the schema. ```elixir defmodule Bar do use Protox, schema: """ syntax = "proto2"; message Foo { optional int32 a = 1 [default = 42]; } """ end iex> %Foo{}.a nil iex> Foo.default(:a) {:ok, 42} ``` -------------------------------- ### Decode Protobuf Data Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Decodes binary data into a message struct. Returns {:ok, msg} on success or {:error, description} on failure. ```elixir @spec decode(binary() :: {:ok, struct()} | {:error, any()}) decode(data) ``` -------------------------------- ### Message Decoding Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Decodes binary data into a message struct. Returns {:ok, struct} on success or {:error, description} on failure. ```APIDOC ## Message Decoding ### Description Decode binary `data` into an structure with the type of the module on which this function is called. Returns `{:ok, msg}` when the decoding was successful and `{:error, description}` in case of an decoding error. ### Function Signature ```elixir @spec decode(binary() :: {:ok, struct()} | {:error, any()}) decode(data) ``` ### Throwing Version ### Description Throwing version of `decode/1`. ### Function Signature ```elixir @spec decode!(binary() :: struct() | no_return()) decode!(data) ``` ``` -------------------------------- ### Encode Elixir Struct to Protobuf Binary Source: https://github.com/ahamez/protox/blob/master/README.md Encodes an Elixir struct into a binary protobuf format using `Protox.encode/1` or `Protox.encode!/1`. The result is iodata for efficiency. ```elixir msg = %Foo{a: 3, b: %{1 => %Baz{}}} {:ok, iodata, iodata_size} = Protox.encode(msg) # or using the bang version {iodata, iodata_size} = Protox.encode!(msg) ``` -------------------------------- ### Message Unknown Fields Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Handles unknown fields encountered during decoding. ```APIDOC ## Message Unknown Fields ### Clear Unknown Fields ### Description Returns a copy of `msg` with all unknown fields removed. ### Function Signature ```elixir @spec clear_unknown_fields(struct() :: struct()) clear_unknown_fields(msg) ``` ### Get Unknown Fields ### Description Get the unknown fields that may have been encountered when decoding data. See [Types](documentation/reference.md#types) section to get a description of `Protox.Types.tag`. ### Function Signature ```elixir @spec unknown_fields(struct() :: [{non_neg_integer(), Protox.Types.tag(), binary()}]) unknown_fields(msg) ``` ### Get Unknown Fields Name ### Description Get the name of the field that stores unknown fields. ### Function Signature ```elixir @spec unknown_fields_name() :: atom() unknown_fields_name(msg) ``` ``` -------------------------------- ### Encode Protobuf Message Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Encodes a message struct into an iodata suitable for files or sockets. Returns {:ok, iodata} on success or {:error, description} on failure. ```elixir @spec encode(struct() :: {:ok, iodata()} | {:error, any()}) encode(msg) ``` -------------------------------- ### Enum Constants Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Retrieves a list of all constants defined within an enum. ```APIDOC ## Enum Constants ### Description Get the list of all the constants of the enum that corresponds to the module on which this function has been called. ### Function Signature ```elixir @spec constants() :: [{integer(), atom()}] constants() ``` ``` -------------------------------- ### Decode Protobuf Binary to Elixir Struct Source: https://github.com/ahamez/protox/blob/master/README.md Decodes a binary protobuf message into an Elixir struct using `Protox.decode/2` or `Protox.decode!/2`, specifying the target struct module. ```elixir {:ok, msg} = Protox.decode(<<8, 3, 18, 4, 8, 1, 18, 0>>, Foo) # or using the bang version msg = Protox.decode!(<<8, 3, 18, 4, 8, 1, 18, 0>>, Foo) ``` -------------------------------- ### Message Schema Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Retrieves the underlying definition of a message. ```APIDOC ## Message Schema ### Description Return the underlying definition of a message, which contains information such as: - syntax (protobuf 2 or 3) - required fields - types of fields ### Function Signature ```elixir @spec schema() :: Protox.MessageSchema.t() schema() ``` ``` -------------------------------- ### Enum Encoding Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Encodes an enum entry to its integer representation. ```APIDOC ## Enum Encoding ### Description Get the integer value of an enum entry. If `enum_entry` does not exist in the enum, it is returned as is. ### Function Signature ```elixir @spec encode(atom() :: integer() | atom()) encode(enum_entry) ``` ``` -------------------------------- ### Enum Decoding Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Decodes an integer value to its corresponding enum entry. ```APIDOC ## Enum Decoding ### Description Get the enum entry of an integer value. If `value` does not correspond to any entry in the enum, it is returned as is. ### Function Signature ```elixir @spec decode(integer() :: atom() | integer()) decode(value) ``` ``` -------------------------------- ### Decode Integer to Enum Entry Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Converts an integer value to its corresponding enum entry (atom). If the value does not match any entry, it is returned as is. ```elixir @spec decode(integer() :: atom() | integer()) decode(value) ``` -------------------------------- ### Clear Unknown Fields from Message Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Returns a copy of the message struct with all unknown fields removed. ```elixir @spec clear_unknown_fields(struct() :: struct()) clear_unknown_fields(msg) ``` -------------------------------- ### Encode Enum Entry to Integer Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Converts an enum entry (atom) to its corresponding integer value. If the entry does not exist, it is returned as is. ```elixir @spec encode(atom() :: integer() | atom()) encode(enum_entry) ``` -------------------------------- ### Message Default Value Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Retrieves the default value for a specified message field. ```APIDOC ## Message Default Value ### Description Get the default value of a message field. Note that for Protobuf 3, the default value is mandated by [the Google reference documentation](https://developers.google.com/protocol-buffers/docs/proto3#default). ### Function Signature ```elixir @spec default(atom() :: {:ok, boolean() | integer() | String.t() | binary() | float()} | {:error, atom()}) default(field_name) ``` ``` -------------------------------- ### Enum Default Value Source: https://github.com/ahamez/protox/blob/master/documentation/reference.md Retrieves the default value of an enum. ```APIDOC ## Enum Default Value ### Description Get the default value of an enum. ### Function Signature ```elixir @spec default() :: atom() default() ``` ``` -------------------------------- ### Access Unknown Fields in Decoded Messages Source: https://github.com/ahamez/protox/blob/master/README.md Unknown fields are retained in decoded messages and can be accessed using the `unknown_fields/1` function. This is useful for forward-compatibility. The function returns a list of tuples, each containing the tag, wire type, and bytes of the unknown field. ```elixir iex> msg = Msg.decode!(<<8, 42, 42, 4, 121, 97, 121, 101, 136, 241, 4, 83>>) %Msg{a: 42, b: "", z: -42, __uf__: [{5, 2, <<121, 97, 121, 101>>}]} ``` ```elixir iex> Msg.unknown_fields(msg) [{5, 2, <<121, 97, 121, 101>>}] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.