Filbert

A BERT serializer and BERT-RPC client for .Net, written in F#

View the Project on GitHub theburningmonk/Filbert

Filbert is a simple BERT serializer and BERT-RPC client for .Net, written in F#.

What is BERT?

BERT is a flexible binary serialization format using the same encoding format as Erlang's external term format but supports only the following data types:

In addition, BERT also specifies a number of complex types as tuples whose first item is the atom bert:

Encoding/Decoding

F#

let mysterWord = [| 131uy; 107uy; 0uy; 8uy; 104uy; 97uy; 122uy; 101uy; 108uy; 110uy; 117uy; 116uy |]
let bert = Dictionary(Map.ofList [(Atom "Filbert", Atom "means"); (ByteList mysterWord, Atom "!")])    

// encode this BERT
use memStream = new MemoryStream()
Filbert.Encoder.encode bert memStream

// now decode it
memStream.Position <- 0L
let bert' = Filbert.Decoder.decode memStream

The full example is available in the F# example project here.

C#

// create a new BERT
var mysterWord = new byte[] { 131, 107, 0, 8, 104, 97, 122, 101, 108, 110, 117, 116 };
var dict = new Dictionary<Bert, Bert>
{
    { Bert.NewAtom("Filbert"), Bert.NewAtom("means") },
    { Bert.NewByteList(mysterWord), Bert.NewAtom("!") }
};

// there's also a helper static method 'FromDict' which constructs a new Bert.Dictionary using
// a standard dictionary type
var bert = Bert.FromDict(dict);

using (var memStream = new MemoryStream())
{
    // encode the BERT
    Filbert.Encoder.encode(bert, memStream);
}

// now decode it
memStream.Position = 0;
var bertClone = Filbert.Decoder.decode(memStream);

The full example is available in the C# example project here

Making BERT-RPC Calls

For more information regarding how BERT-RPC works, please refer to the BERT-RPC spec.

Suppose there is a nat Erlang module running on the BERT-RPC server, which looks like this:

-module(nat).
-export([add/2]).

add(A, B) -> A + B.

F#

let client = Filbert.Rpc.BertRpcClient.Start(serviceUrl, portNumber)

// synchronous example
let result = client.Call("nat", "add", Integer 1, Integer 100) |> Async.RunSynchronously

// asynchronous example
async {
    let! result = client.Call("nat", "add", Integer 1, Integer 100)
    ... // do something with the result, printf, etc.
}
|> Async.Start

The full example is available in the F# example project here.

C#

var client = Filbert.Rpc.BertRpcClient.Start(serviceUrl, portNumber)

// synchronous example
var result = client.CallAsTask("nat", "add", Bert.NewInteger(1), Bert.NewInteger(100))
                   .Result;

// asynchronous example (provided that this is an async method)
var result2 = await client.CallAsTask("nat", "add", Bert.NewInteger(1), Bert.NewInteger(100));

The full example is available in the C# example project here.

NuGet

Download and install Filbert using NuGet.

NuGet package

Updates

Follow the official twitter account @FilbertFs for updates!