View Source Msgpax.Ext (Msgpax v2.4.0)

A struct used to represent the MessagePack Extension type.

examples

Examples

Let's say we want to be able to serialize a custom type that consists of a byte data repeated count times. We could represent this as a RepByte struct in Elixir:

defmodule RepByte do
  defstruct [:data, :count]
end

A simple (albeit not space efficient) approach to encoding such data is simply a binary containing data for count times: %RepByte{data: ?a, count: 2} would be encoded as "aa".

We can now define the Msgpax.Packer protocol for the RepByte struct to tell Msgpax how to encode this struct (we'll choose 10 as an arbitrary integer to identify the type of this extension).

defimpl Msgpax.Packer, for: RepByte do
  @rep_byte_ext_type 10

  def pack(%RepByte{data: byte, count: count}) do
    @rep_byte_ext_type
    |> Msgpax.Ext.new(String.duplicate(<<byte>>, count))
    |> Msgpax.Packer.pack()
  end
end

Now, we can pack RepBytes:

iex> packed = Msgpax.pack!(%RepByte{data: ?a, count: 3})
iex> Msgpax.unpack!(packed)
#Msgpax.Ext<10, "aaa">

unpacking

Unpacking

As seen in the example above, since the RepByte struct is packed as a MessagePack extension, it will be unpacked as that extension later on; what we may want, however, is to unpack that extension back to a RepByte struct.

To do this, we can pass an :ext option to Msgpax.unpack/2 (and other unpacking functions). This option has to be a module that implements the Msgpax.Ext.Unpacker behaviour; it will be used to unpack extensions to arbitrary Elixir terms.

For our RepByte example, we could create an unpacker module like this:

defmodule MyExtUnpacker do
  @behaviour Msgpax.Ext.Unpacker
  @rep_byte_ext_type 10

  @impl true
  def unpack(%Msgpax.Ext{type: @rep_byte_ext_type, data: data}) do
    <<byte, _rest::binary>> = data
    {:ok, %RepByte{data: byte, count: byte_size(data)}}
  end
end

With this in place, we can now unpack a packed RepByte back to a RepByte struct:

iex> packed = Msgpax.pack!(%RepByte{data: ?a, count: 3})
iex> Msgpax.unpack!(packed, ext: MyExtUnpacker)
%RepByte{data: ?a, count: 3}

Link to this section Summary

Functions

Creates a new Msgpax.Ext struct.

Link to this section Types

@type t() :: %Msgpax.Ext{data: iodata(), type: type()}
@type type() :: 0..127

Link to this section Functions

Creates a new Msgpax.Ext struct.

type must be an integer in 0..127 and it will be used as the type of the extension (whose meaning depends on your application). data must be an iodata containing the serialized extension (whose serialization depends on your application).

examples

Examples

iex> Msgpax.Ext.new(24, "foo")
#Msgpax.Ext<24, "foo">

iex> Msgpax.Ext.new(25, 'bar')
#Msgpax.Ext<25, 'bar'>