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.
Elixir | MessagePack | Elixir |
---|---|---|
nil | nil | nil |
true | boolean | true |
false | boolean | false |
-1 | integer | -1 |
1.25 | float | 1.25 |
N/A¹ | NaN | Msgpax.NaN ² |
N/A¹ | +infinity | Msgpax.Infinity ² |
N/A¹ | -infinity | Msgpax.NegInfinity ² |
:ok | string | "ok" |
Atom | string | "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
@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) iftrue
, this function returns the encoded term as iodata, iffalse
as a binary. Defaults totrue
.
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>>}
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>>
@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>>
@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>>
@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) iftrue
, then binaries are decoded asMsgpax.Bin
structs instead of plain Elixir binaries. Defaults tofalse
.:ext
- (module) a module that implements theMsgpax.Ext.Unpacker
behaviour. For more information, see the docs forMsgpax.Ext.Unpacker
.:nonfinite_floats
- (boolean) iftrue
, deserializes NaN and ±infinity to "signalling" atoms (see the "Data conversion" section), otherwise errors. Defaults tofalse
.
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>>>
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>>>
@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}}}
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