Skip to content

LeonardBesson/bincode

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bincode

Hex Version Hex Docs

CI MIT License

Bincode allows you to share data between Elixir and Rust using Rust's Bincode binary format.

You can implement your custom serialization manually, but for most use cases you can simply declare the Rust structs and enums using Bincode.Structs.declare_struct/3 and Bincode.Structs.declare_enum/3

Supported types

Most Rust types are supported, plus user defined structs and enums.

Rust Bincode notation Elixir typespec
u8 :u8 non_neg_integer
... ... ...
u128 :u128 non_neg_integer
i8 :i8 integer
... ... ...
i128 :i128 integer
f32 :f32 float
f64 :f64 float
bool :bool boolean
String :string binary
(u32, String) {:u32, :string} {non_neg_integer, binary}
Option<f32> {:option, :f32} float | nil
Vec<String> {:list, :string} [binary]
HashMap<i64, String> {:map, {:i64, :string}} %{required(integer) => binary}
HashSet<u8> {:set, :u8} MapSet.t(non_neg_integer)

User defined types such as structs and enums can be nested, in this case the type is the fully qualified module name. See documentation for Bincode.Structs.declare_struct/3.

The endianness is little since that's the default used by Bincode. Tuples are implemented for a max size of 12 by default. That should be enough for most practical cases but if you need to serialize tuples with more elements you can set max_tuple_size in the mix config, like so:

config :bincode, max_tuple_size: 23

Examples

Consider the typical example where we want to send data structures across the network. Here with a Rust client and Elixir server:

#[derive(Serialize, Deserialize)]
pub struct PacketSendMessage {
  pub from: u64,
  pub to: u64,
  pub content: String,
}

pub fn send_message(sender_id: u64, receiver_id: u64) {
  let message = PacketSendMessage {
      from: sender_id,
      to: receiver_id,
      content: "hello!".to_owned()
  };
  let encoded: Vec<u8> = bincode::serialize(&message).unwrap();

  // now send "encoded" to Elixir app
}

On the Elixir side you can simply declare the same packet struct and deserialize the received bytes:

defmodule Packets do
  import Bincode.Structs

  declare_struct(PacketSendMessage,
    from: :u64,
    to: :u64,
    content: :string
  )
end

alias Packets.PacketSendMessage

# Receive "data" from the network
{:ok, {%PacketSendMessage{} = message, rest}} = PacketSendMessage.deserialize(data)
Logger.info("Received message packet #{inspect(message)}")

Installation

Add bincode to your list of dependencies in mix.exs:

def deps do
  [
    {:bincode, "~> 0.3.0"}
  ]
end

Documentation

https://hexdocs.pm/bincode.

About

Binary serialization for Elixir

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages