Bson.Decoder

Decoder for Bson documents

Source

Summary

document(bsonbuffer, opts \\ %Bson.Decoder{})

Decodes the first document of a Bson buffer

elist_to_atom_map(elist)

Transform an elist to a map with atom keys

elist_to_hashdict(elist)

Transform an elist to a hashdict

elist_to_keyword(elist)

Transform an elist to a Keyword

elist_to_map(elist)

Transform an elist to a map

identity(elist)

Identity function

Functions

document(bsonbuffer, opts \\ %Bson.Decoder{})

Decodes the first document of a Bson buffer

  • bsonbuffer contains one or several bson documents
  • opts must be a struct %Bson.Decoder{} that can be used to configure how the decoder handels document and binary elements. By default the root document and any embeded documents are processed using Bson.Decoder.elist_to_atom_map/1 that receives an element list and returns and Elixir term. Binary element are processed by Bson.Bin.new/2.

Others alternatives for processing parsed documents are available:

  • Bson.Decoder.elist_to_map
  • Bson.Decoder.elist_to_hashdict
  • Bson.Decoder.elist_to_keyword

usage:

iex> [%{},
...>  %{a: 3},
...>  %{a: "r"},
...>  %{a: ""},
...>  %{a: 1, b: 5}
...> ] |> Enum.all? fn(term) -> assert term == term |> Bson.encode |> Bson.decode end
true

iex> term = %{
...> a:  4.1,
...> b:  2}
...> assert term == term |> Bson.encode |> Bson.decode
true

# Document format error
iex> "" |> Bson.decode
%Bson.Decoder.Error{what: :"document size is 0, must be > 4", acc: [], rest: {0, ""}}
iex> <<4, 0, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: :"document size is 4, must be > 4", acc: [], rest: {4, <<4, 0, 0, 0>>}}
iex> <<4, 0, 0, 0, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: :"document size", rest: {4, <<4, 0, 0, 0, 0, 0>>}}
iex> <<5, 0, 0, 0, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: :buffer_not_empty, acc: %{}, rest: <<0>>}
iex> <<5, 0, 0, 0, 0, 0>> |> Bson.Decoder.document
{%{}, <<0>>}
iex> <<5, 0, 0, 0, 1>> |> Bson.decode
%Bson.Decoder.Error{what: :"document trail", acc: %{}, rest: {0, <<1>>}}
iex> <<5, 0, 0, 0, 0, 0>> |> Bson.Decoder.document
{%{}, <<0>>}

# Unsupported element kind (here 203)
iex> <<27, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 203, 98, 0, 12, 0, 0, 0, 16, 99, 0, 3, 0, 0, 0, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: ["b", {:kind, 203}], acc: [[{"a", 1}]], rest: {12, <<12, 0, 0, 0, 16, 99, 0, 3, 0, 0, 0, 0, 0>>}}

# Float encoding
# %{a: 1, b: ~~~} - wrong float in 'b'
iex> <<27, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 1, 98, 0, 255, 255, 255, 255, 255, 255, 255, 255, 16, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: ["b", :float], acc: [[{"a", 1}]], rest: {12, <<255, 255, 255, 255, 255, 255, 255, 255, 16, 0, 0>>}}

# %{a: 1, b: %{c: 1, d: ~~~}} - wrong float in 'd'
iex> <<38, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 3, 98, 0, 23, 0, 0, 0, 16, 99, 0, 1, 0, 0, 0, 1, 100, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0>>  |> Bson.decode
%Bson.Decoder.Error{what: ["b", "d", :float], acc: [[{"a", 1}], [{"c", 1}]], rest: {8, <<255, 255, 255, 255, 255, 255, 255, 255, 0, 0>>}}

# Cstring
#                                                    | should be 3
iex> <<27, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 2, 98, 0, 1, 0, 0, 0, 99, 98, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: ["b", :bytestring], acc: [[{"a", 1}]], rest: {8, <<99, 98, 0, 0>>}}
#                                                    | should be > 1
iex> <<27, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 2, 98, 0, 1, 0, 0, 0, 99, 98, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: ["b", :bytestring], acc: [[{"a", 1}]], rest: {8, <<99, 98, 0, 0>>}}
#                                                    | missing string length
iex> <<21, 0, 0, 0, 16, 97, 0, 1, 0, 0, 0, 2, 98, 0, 99, 0, 0>> |> Bson.decode
%Bson.Decoder.Error{what: ["b", :string], acc: [[{"a", 1}]], rest: {6, <<99, 0, 0>>}}
Source
elist_to_atom_map(elist)

Transform an elist to a map with atom keys

iex> [{"a", 1}, {"b", 2}] |> Bson.Decoder.elist_to_atom_map
%{a: 1, b: 2}
Source
elist_to_hashdict(elist)

Transform an elist to a hashdict

iex> [{"a", 1}, {"b", 2}] |> Bson.Decoder.elist_to_hashdict
%HashDict{} |> Dict.put("a", 1) |> Dict.put("b", 2)
Source
elist_to_keyword(elist)

Transform an elist to a Keyword

iex> [{"a", 1}, {"b", 2}] |> Bson.Decoder.elist_to_keyword
[a: 1, b: 2]
Source
elist_to_map(elist)

Transform an elist to a map

iex> [{"a", 1}, {"b", 2}] |> Bson.Decoder.elist_to_map
%{"a" => 1, "b" => 2}
Source
identity(elist)

Identity function

Source