Msgpax v2.0.0 Msgpax

This module provides functions for serializing and de-serializing Elixir terms using the MessagePack format.

Data conversion

The following table shows how Elixir types are serialized to MessagePack types and how MessagePack types are de-serialized back to Elixir types.

ElixirMessagePackElixir
nilnilnil
truebooleantrue
falsebooleanfalse
-1integer-1
1.25float1.25
:okstring"ok"
Atomstring"Elixir.Atom"
"str"string"str"
"\xFF\xFF"string"\xFF\xFF"
#Msgpax.Bin<"\xFF">binary"\xFF"
%{foo: "bar"}map%{"foo" => "bar"}
[foo: "bar"]map%{"foo" => "bar"}
[1, true]array[1, true]
#Msgpax.Ext<4, "02:12">extension#Msgpax.Ext<4, "02:12">

Summary

Functions

Serializes term

Works as pack/1, but raises if there’s an error

De-serializes the given iodata

Works like unpack/2, but raises in case of errors

De-serializes part of the given iodata

Works like unpack_slice/2 but raises in case of error

Functions

pack(term, options \\ [])
pack(term, Keyword.t) ::
  {:ok, iodata} |
  {:error, Msgpax.PackError.t}

Serializes term.

This function returns iodata by default; if you want to force the result to be a binary, you can use IO.iodata_to_binary/1 or use the :iodata option (see the “Options” section below).

This function returns {:ok, iodata} if the serialization is successful, {:error, exception} otherwise, where exception is a Msgpax.PackError struct which can be raised or converted to a more human-friendly error message with Exception.message/1. See Msgpax.PackError for all the possible reasons for a packing error.

Options

  • :iodata - (boolean) if true, this function returns the encoded term as iodata, if false as a binary.

Examples

iex> {:ok, packed} = Msgpax.pack("foo")
iex> IO.iodata_to_binary(packed)
<<163, 102, 111, 111>>

iex> Msgpax.pack(20000000000000000000)
{:error, %Msgpax.PackError{reason: {:too_big, 20000000000000000000}}}

iex> Msgpax.pack("foo", iodata: false)
{:ok, <<163, 102, 111, 111>>}
pack!(term, options \\ [])
pack!(term, Keyword.t) :: iodata | no_return

Works as pack/1, but raises if there’s an error.

This function works like pack/1, except it returns the term (instead of {:ok, term}) if the serialization is successful or raises a Msgpax.PackError exception otherwise.

Options

This function accepts the same options as pack/2.

Examples

iex> "foo" |> Msgpax.pack!() |> IO.iodata_to_binary()
<<163, 102, 111, 111>>

iex> Msgpax.pack!(20000000000000000000)
** (Msgpax.PackError) value is too big: 20000000000000000000

iex> Msgpax.pack!("foo", iodata: false)
<<163, 102, 111, 111>>
unpack(iodata, options \\ [])
unpack(iodata, Keyword.t) ::
  {:ok, any} |
  {:error, Msgpax.UnpackError.t}

De-serializes the given iodata.

This function de-serializes the given iodata into an Elixir term. It returns {:ok, term} if the de-serialization is successful, {:error, exception} otherwise, where exception is a Msgpax.UnpackError struct which can be raised or converted to a more human-friendly error message with Exception.message/1. See Msgpax.UnpackError for all the possible reasons for an unpacking error.

Options

  • :binary - (boolean) if true, then binaries are decoded as Msgpax.Bin structs instead of plain Elixir binaries.
  • :ext - (module) a module that implements the Msgpax.Ext.Unpacker behaviour. For more information, see the docs for Msgpax.Ext.Unpacker.

Examples

iex> Msgpax.unpack(<<163, "foo">>)
{:ok, "foo"}

iex> Msgpax.unpack(<<163, "foo", "junk">>)
{:error, %Msgpax.UnpackError{reason: {:excess_bytes, "junk"}}}

iex> packed = Msgpax.pack!(Msgpax.Bin.new(<<3, 18, 122, 27, 115>>))
iex> {:ok, bin} = Msgpax.unpack(packed, binary: true)
iex> bin
#Msgpax.Bin<<<3, 18, 122, 27, 115>>>
unpack!(iodata, options \\ [])
unpack!(iodata, Keyword.t) :: any | no_return

Works like unpack/2, but raises in case of errors.

This function works like unpack/2, but it returns term (instead of {:ok, term}) if de-serialization is successful, otherwise raises a Msgpax.UnpackError exception.

Example

iex> Msgpax.unpack!(<<163, "foo">>)
"foo"

iex> Msgpax.unpack!(<<163, "foo", "junk">>)
** (Msgpax.UnpackError) found excess bytes: "junk"

iex> packed = Msgpax.pack!(Msgpax.Bin.new(<<3, 18, 122, 27, 115>>))
iex> Msgpax.unpack!(packed, binary: true)
#Msgpax.Bin<<<3, 18, 122, 27, 115>>>
unpack_slice(iodata, options \\ [])
unpack_slice(iodata, Keyword.t) ::
  {:ok, any, binary} |
  {:error, Msgpax.UnpackError.t}

De-serializes part of the given iodata.

This function works like unpack/2, but instead of requiring the input to be a MessagePack-serialized term with nothing after that, it accepts leftover bytes at the end of iodata and only de-serializes the part of the input that makes sense. It returns {:ok, term, rest} if de-serialization is successful, {:error, exception} otherwise (where exception is a Msgpax.UnpackError struct).

See unpack/2 for more information on the supported options.

Examples

iex> Msgpax.unpack_slice(<<163, "foo", "junk">>)
{:ok, "foo", "junk"}

iex> Msgpax.unpack_slice(<<163, "fo">>)
{:error, %Msgpax.UnpackError{reason: {:invalid_format, 163}}}
unpack_slice!(iodata, options \\ [])
unpack_slice!(iodata, Keyword.t) ::
  {any, binary} |
  no_return

Works like unpack_slice/2 but raises in case of error.

This function works like unpack_slice/2, but returns just {term, rest} if de-serialization is successful and raises a Msgpax.UnpackError exception if it’s not.

Examples

iex> Msgpax.unpack_slice!(<<163, "foo", "junk">>)
{"foo", "junk"}

iex> Msgpax.unpack_slice!(<<163, "fo">>)
** (Msgpax.UnpackError) invalid format, first byte: 163