View Source BorshEx (borsh_ex v0.1.0)
Elixir implementation of Binary Object Representation Serializer for Hashing (borsh)
Usage
Define schema using BorshEx.Schema
defmodule SubData do
use BorshEx.Schema
defstruct address: nil
borsh_schema do
field :address, "string"
end
end
defmodule Data do
use BorshEx.Schema
defstruct name: nil
borsh_schema do
field :id, "u16"
field :sub_data, SubData
end
end
Once schema is define, we are able to serialize a struct into a binary or deserialize to a struct.
iex> data = %Data{id: 45, sub_data: %SubData{address: "Hello world!"}}
%Data{id: 45, sub_data: %SubData{address: "Hello world!"}}
iex> bistring = Data.serialize(data)
<<45, 0, 12, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33>>
iex> data = Data.deserialize(bitstring)
{:ok, %Data{id: 45, sub_data: %SubData{address: "Hello world!"}}}
In some case the bitstring is longer than necessary, some bytes are not used
iex> bitstring = <<45, 0, 12, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 5, 0>>
<<45, 0, 12, 0, 0, 0, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 10, 5, 0>>
iex> data = Data.deserialize(bitstring)
{:error, %Data{id: 45, sub_data: %SubData{address: "Hello world!"}}, <<5, 0>>}
<<5, 0>>
returned are unused bytes.
Basic types
type | example |
---|---|
u8 , u16 , u32 , u64 | field :id, "u8" |
i8 , i16 , i32 , i64 | field :id, "i8" |
boolean | field :id, "bool" |
string | field :id, "string" |
struct | field :id, MyStruct |
Complex types
All types can be used in a more complex one
Array
An array can have a fixed size
# ids is a list of 32 `u16` values
# sub_data is a list of 32 Subdata strut
borsh_schema do
field :ids, {"array", {"u16", 32}}
field :sub_data, {"array", {Subdata, 32}}
end
Or variable length
# ids is a list `u16` value
# sub_data is a list of Subdata strut
borsh_schema do
field :ids, {"array", "u16"}
field :sub_data, {"array", {Subdata, 32}}
end
Option
a field can be optional
# if name can be nil or a string
borsh_schema do
field :name, {"option", "string"}
end
iex> data = %Data{name: nil}
%Data{name: nil}
iex> Data.serialize(data)
<<0>>
iex> data = %Data{name: "Hello"}
%Data{name: "Hello"}
iex> Data.serialize(data)
<<1, 5, 0, 0, 0, 72, 101, 108, 108, 111>>