# Bcs
Pure Elixir encoder/decoder for [BCS format](https://github.com/diem/bcs).
## Features
Encoder/Decoder for:
- [x] Booleans
- [x] Signed 8-bit, 16-bit, 32-bit, 64-bit, and 128-bit integers
- [x] Unsigned 8-bit, 16-bit, 32-bit, 64-bit, and 128-bit integers
- [x] Option
- [x] Unit (an empty value)
- [x] Fixed and variable length sequences
- [x] UTF-8 Encoded Strings
- [x] Tuples
- [x] Structures (aka “structs”)
- [x] Externally tagged enumerations (aka “enums”)
- [x] Maps
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `bcs` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:bcs, "~> 0.1.0"}
]
end
```
## Usage
```elixir
# Define the struct
defmodule MyStruct do
@derive {Bcs.Struct,
label: :string,
chars: [:u8 | 4], # <<= we use improper list for fixed length array
boolean: :bool,
maps: %{:u8 => :string},
}
defstruct [:label, :chars, :boolean, :maps, :field]
end
my_struct = %MyStruct{
label: "hello",
chars: 'abcd',
boolean: true,
maps: %{1 => "1", 2 => "2"},
field: "this field will be ignored"
}
# encode
my_struct
|> Bcs.encode()
# then decode
|> Bcs.decode(MyStruct)
```
## Define field Types
Rust Type | Syntax
-------------|-------------
`u8`, `s8`, `u16`, `u256`, ... | `:u8`, `:s8`, `:u16`, `:u256`, ...
`bool` | `:bool`
`()` | `nil`
`Option<T>` | `[t \| nil]`
`[T]` | `[t]`
`[T; N]` | `[t \| n]`
`String` | `:string`
`(T1, T2)` | `{t1, t2}`
`MyStruct` | `MyStruct`
`enum E` | `E`
`Map<K, V>` | `%{k => v}`
Also we have a special type for treating `[u8]` as binary instead of charlist
`[u8]` | `[:byte]`
`[u8; N]` | `[:byte \| n]`
### Define Tagged Enums
```elixir
defmodule Foo do
use Bcs.TaggedEnum, [
{:variant0, :u16},
{:variant1, :u8},
{:variant2, :string},
:variant3
]
end
```
Some valid values for type `Foo`: `{:variant0, 42}`, `{:variant2, "hello"}`, `:variant3`, etc.