Current section
Files
Jump to
Current section
Files
README.md
| | || ---------- | ------------ || Package |  || Support |  || CI (`master`) | [](https://travis-ci.com/revelrylabs/exdr) || Coverage |  |# XDRXDR is an open data format for serializing and de-serializing structured data based on shared definitions,defined in [RFC 4506](http://tools.ietf.org/html/rfc4506.html). This library aims to provide an idiomaticinterface for working with XDR data in Elixir.## DocumentationDetailed documentation and examples can be found at [https://hexdocs.pm/exdr](https://hexdocs.pm/exdr).## InstallationAdd [`exdr`](https://hex.pm/packages/exdr) to your list of dependencies in `mix.exs`:```elixirdef deps do [ {:exdr, "~> 0.1.0"} ]end```## Basic UsageTo work with XDR, an application needs to be able to do five things:1. Define the types and structure of the data2. Create instances of the data types with specific values3. Encode that structured data into a binary representation4. Decode a binary representation into structured, typed data5. Extract the raw values from the data structuresThe main `XDR` module provides functions for each of these operations.These examples illustrate their usage:### Building data typesFully-determined types can be built by configuring and combining the predefined XDR types.```elixirint_type = XDR.build_type(XDR.Type.Int)name_type = XDR.build_type(XDR.Type.VariableOpaque)five_ints_type = XDR.build_type(XDR.Type.Array, type: int_type, length: 5)student_type = XDR.build_type(XDR.Type.Struct, name: name_type, quiz_scores: five_ints_type, homework_scores: five_ints_type)```The configuration required by each built-in type varies. See the [documentation](https://hexdocs.pm/exdr/XDR.html#build_type/2) for more details.### Adding specific valuesOnce the data types are defined, values can be built. Again, the applicable valuesdepend on the data types.```elixir{:ok, single_score} = XDR.build_value(int_type, 92){:ok, single_name} = XDR.build_value(name_type, "Student A")```Complex data types can be built up all at once, rather than having to initializeeach subsidiary value:```elixir{:ok, student_a} = XDR.build_value(student_type, name: "Student A", quiz_scores: [100, 93, 60, 88, 100], homework_scores: [66, 80, 100, 99, 0])```### Encoding dataOnce data structures have been defined and specific values created, they can be encodedinto a binary XDR representation:```elixir{:ok, single_score_encoding} = XDR.encode(single_score){:ok, single_name_encoding} = XDR.encode(single_name){:ok, student_a_encoding} = XDR.encode(student_a)```### Decoding dataAny XDR implementation with access to the same type definitions will be able to decode the binaryrepresentations into structured data.```elixir{:ok, single_score_decoded} = XDR.decode(int_type, single_score_encoding){:ok, single_name_decoded} = XDR.decode(name_type, single_name_encoding){:ok, student_a_decoded} = XDR.decode(student_type, student_a_encoding)# Upon decoding, these values are fully-fledged XDR types%XDR.Type.Struct{fields: fields} = student_a_decoded```### Extracting underlying valuesTo use the data, we probably want to extract the raw values from the XDR metadata:```elixir{:ok, student_a_data} = XDR.extract_value(student_a_decoded)# this should match what we put in originally[ name: "Student A", quiz_scores: [100, 93, 60, 88, 100], homework_scores: [66, 80, 100, 99, 0]] = student_a_data```## Custom XDR Type DefinitionsWhen building complex apps, it's not convenient to have to build up the typesmanually every time time they're needed, so an application can predefineits XDR types and compile them into the application. The `XDR.Base` moduleprovides the `define_type` macro for registering and accessing application-specifictypes using the `define_type` macro.```elixirdefmodule MyXDR @moduledoc """ We can define custom types in our own module and then work with them through that module. All of the functions demonstrated above on XDR are available on MyXDR, and we can use simple string names to reference our predefined XDR types. """ use XDR.Base # `define_type` works just like `build_type` with an extra `name` parameter at the front define_type("Student", Struct, name: "Name", quiz_scores: "Scores", homework_scores: "Scores", ) define_type("Scores", Array, type: "Score", length: 5 ) define_type("Score", Int) define_type("Name", VariableOpaque)end# using the predefined types in our code{:ok, student_b} = MyXDR.build_value!("Student", name: "Student B", quiz_scores: [93, 60, 88, 100, 84], homework_scores: [80, 100, 99, 0, 90]){:ok, encoded_student_b} = MyXDR.encode(student_b){:ok, decoded_student_b} = MyXDR.decode("Student", encoded_student_b)```For a real-life example, see the [`Stellar.XDR`](https://github.com/revelrylabs/exdr/tree/master/test/support/stellar/Stellar.XDR_generated.ex) module, which was generated from [the Stellar type definitions](https://github.com/stellar/js-stellar-base/tree/master/xdr) using the [xdrgen tool](https://github.com/stellar/xdrgen).## Contributing and DevelopmentSee [CONTRIBUTING.md](https://github.com/revelrylabs/exdr/blob/master/CONTRIBUTING.md)for guidance on how to develop for this library.Bug reports and pull requests are welcome on GitHub at https://github.com/revelrylabs/exdr. Check out [CONTRIBUTING.md](https://github.com/revelrylabs/exdr/blob/master/CONTRIBUTING.md) for more info.Everyone is welcome to participate in the project. We expect contributors toadhere to the Contributor Covenant Code of Conduct (see [CODE_OF_CONDUCT.md](https://github.com/revelrylabs/exdr/blob/master/CODE_OF_CONDUCT.md)).## ReleasesSee [RELEASES.md](https://github.com/revelrylabs/exdr/blob/master/RELEASES.md) for details about the release process.## LicenseSee [LICENSE](https://github.com/revelrylabs/exdr/blob/master/LICENSE) for details.