defprotocol Lapin.Message.Payload do @moduledoc """ You can use this protocol to implement a custom message payload transformation. For example you could implement a JSON message with a predefined structure by first implementing a struct for your payload: ```elixir defmodule Example.Payload do defstruct [a: "a", b: "b", c: nil] end ``` and then providing an implementation of `Lapin.Message.Payload` for it: ```elixir defimpl Lapin.Message.Payload, for: Example.Payload do def content_type(_payload), do: "application/json" def encode(payload), do: Poison.encode(payload) def decode_into(payload, data), do: Poison.decode(data, as: payload) end ``` Please note you will need to add the `poison` library as a dependency on in your project `mix.exs` for this to work. Lapin will automatically encode and set the `content-type` property on publish. To decode messages before consuming, implement the `payload_for/2` callback of `Lapin.Connection` and return an instance of the payload to decode into. ```elixir defmodule Example.Connection do def payload_for(_channel, _message), do: %Example.Payload{} end ``` The default implementation simply returns the unaltered binary data and sets the message `content-type` property to `nil`. """ @typedoc "Data type implementing the `Lapin.Message.Payload` protocol" @type t :: term @typedoc "MIME content-type as defined by RFC 2045" @type content_type :: String.t() | nil @typedoc "Encode function return values" @type on_encode :: {:ok, binary} | {:error, term} @typedoc "Decode function return values" @type on_decode :: {:ok, t} | {:error, term} @doc """ Returns the message `content-type` """ @spec content_type(t) :: content_type def content_type(payload) @doc """ Returns the encoded payload body """ @spec encode(t) :: on_encode def encode(payload) @doc """ Returns the payload with message data decoded """ @spec decode_into(t, binary) :: on_decode def decode_into(payload, data) end