View Source Msgpax (Msgpax v2.4.0)

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

data-conversion

Data conversion

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

ElixirMessagePackElixir
nilnilnil
truebooleantrue
falsebooleanfalse
-1integer-1
1.25float1.25
N/A¹NaNMsgpax.NaN²
N/A¹+infinityMsgpax.Infinity²
N/A¹-infinityMsgpax.NegInfinity²
:okstring"ok"
Atomstring"Elixir.Atom"
"text"string"text"
"\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">
#DateTime<2017-12-06 00:00:00Z>extension#DateTime<2017-12-06 00:00:00Z>

¹ Msgpax.Packer provides helper functions to facilitate the serialization of natively unsupported data types.

² NaN and ±infinity are not enabled by default. See unpack/2 for for more information.

³ To deserialize back to Msgpax.Bin structs see the unpack/2 options.

Link to this section Summary

Functions

Serializes the given term.

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

Serializes term and turns the result into a Msgpax.Fragment.

Works as pack_fragment/2, but raises if there's an error.

Deserializes the given iodata.

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

Deserializes part of the given iodata.

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

Link to this section Functions

Link to this function

pack(term, options \\ [])

View Source
@spec pack(term(), Keyword.t()) ::
  {:ok, iodata()} | {:error, Msgpax.PackError.t() | Exception.t()}

Serializes the given 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

Options

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

examples

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>>}
Link to this function

pack!(term, options \\ [])

View Source
@spec 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

Options

This function accepts the same options as pack/2.

examples

Examples

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

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

iex> Msgpax.pack!("foo", iodata: false)
<<163, 102, 111, 111>>
Link to this function

pack_fragment(term, options \\ [])

View Source
@spec pack_fragment(term(), Keyword.t()) ::
  {:ok, Msgpax.Fragment.t()} | {:error, Msgpax.PackError.t() | Exception.t()}

Serializes term and turns the result into a Msgpax.Fragment.

This function returns {:ok, fragment} 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.

This is useful for optimization, for instance, to avoid packing heavy terms repetitively.

Another good use case for fragments would be data encapsulation. For example, if we want to "interpolate" some MessagePack data into the payload without having to unpack and pack them.

options

Options

This function accepts the same options as pack/2.

examples

Examples

iex> {:ok, fragment} = Msgpax.pack_fragment("HUGE")
iex> {:ok, packed} = Msgpax.pack([fragment, fragment])
iex> IO.iodata_to_binary(packed)
<<146, 164, 72, 85, 71, 69, 164, 72, 85, 71, 69>>
Link to this function

pack_fragment!(term, options \\ [])

View Source
@spec pack_fragment!(term(), Keyword.t()) :: Msgpax.Fragment.t() | no_return()

Works as pack_fragment/2, but raises if there's an error.

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

options

Options

This function accepts the same options as pack_fragment/2.

examples

Examples

iex> fragment = Msgpax.pack_fragment!("HUGE")
iex> {:ok, packed} = Msgpax.pack([fragment, fragment])
iex> IO.iodata_to_binary(packed)
<<146, 164, 72, 85, 71, 69, 164, 72, 85, 71, 69>>
Link to this function

unpack(iodata, options \\ [])

View Source
@spec unpack(iodata(), Keyword.t()) :: {:ok, any()} | {:error, Msgpax.UnpackError.t()}

Deserializes the given iodata.

This function deserializes the given iodata into an Elixir term. It returns {:ok, term} if the deserialization 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

Options

  • :binary - (boolean) if true, then binaries are decoded as Msgpax.Bin structs instead of plain Elixir binaries. Defaults to false.

  • :ext - (module) a module that implements the Msgpax.Ext.Unpacker behaviour. For more information, see the docs for Msgpax.Ext.Unpacker.

  • :nonfinite_floats - (boolean) if true, deserializes NaN and ±infinity to "signalling" atoms (see the "Data conversion" section), otherwise errors. Defaults to false.

examples

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>>>
Link to this function

unpack!(iodata, options \\ [])

View Source
@spec 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 deserialization is successful, otherwise raises a Msgpax.UnpackError exception.

example

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>>>
Link to this function

unpack_slice(iodata, options \\ [])

View Source
@spec unpack_slice(iodata(), Keyword.t()) ::
  {:ok, any(), binary()} | {:error, Msgpax.UnpackError.t()}

Deserializes 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 deserializes the part of the input that makes sense. It returns {:ok, term, rest} if deserialization is successful, {:error, exception} otherwise (where exception is a Msgpax.UnpackError struct).

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

examples

Examples

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

iex> Msgpax.unpack_slice(<<163, "fo">>)
{:error, %Msgpax.UnpackError{reason: {:invalid_format, 163}}}
Link to this function

unpack_slice!(iodata, options \\ [])

View Source
@spec 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 deserialization is successful and raises a Msgpax.UnpackError exception if it's not.

examples

Examples

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

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