Nestru.Decoder protocol (Nestru v1.0.1) View Source

Link to this section Summary

Functions

Returns the hint of how to decode the struct fields.

Link to this section Types

Link to this section Functions

Link to this function

decode_fields_hint(empty_struct, context, value)

View Source

Returns the hint of how to decode the struct fields.

The first argument is an empty struct value adopting the protocol.

The second argument is the context value given to the Nestru.decode/3 function call.

The third argument is a map or a binary to be decoded into the struct.

If the function returns {:ok, hint}, then the hint is expected to be a map or an instance of the decodable struct.

When the map is returned then, key-value pairs give the decoding hint about the struct's fields with the key equal to field's name and the value specifying the following:

  • A module's atom (f.e. Module) specifies that the appropriate field's value should be decoded as a nested struct defined in the module. Each field of the nested struct will be decoded recursively.

  • A one-element list with the module's atom (f.e. [Module]) specifies that the appropriate field's value should be decoded as a list of structs. It's equivalent of returning &Nestru.decode_from_list(&1, module).

  • An anonymous function with arity 1 (f.e. &my_fun/1) specifies that the appropriate field's value should be returned from the function. The function's only argument is the value from the map to be decoded, and it is expected to return {:ok, term}, {:error, %{message: term, path: list}}, or {:error, term}.

Any field missing the key in the hint receives the value as-is from the input map. The %{} empty hint value defines that all fields of the struct take all values from the input map unmodified.

When the returned hint is an instance of the decodable struct, then it is returned as is.

If the function returns {:ok, nil}, then the decoded struct's value is nil.

If the function returns {:error, message} tuple, then decoding stops, and the error is bypassed to the caller.

Any other return value raises an error.

To generate the implementation of the function for the given struct in short form, set the @derive module attribute to the tuple of Nestru.Decoder and the :hint option specifying the hint map to be returned.

The default implementation derived for the struct pulls all values from the input map unmodified.

See the examples below.

Examples

def Supplier do
  # Derive the default implementation
  @derive Nestru.Decoder

  defstruct [:id, :name]
end

def FruitBox.Fruit do
  # Give a hint in a compact form with deriving the protocol
  @derive {Nestru.Decoder, hint: %{vitamins: [Vitamin], supplier: Supplier}}

  defstruct [:vitamins, :supplier]
end

defmodule FruitBox do
  defstruct [:items]

  # Implement the function returning the hint explicitly
  defimpl Nestru.Decoder do
    def decode_fields_hint(_empty_struct, _context, value) do
      # Give a function to decode the list field as a hint, other fields are copied as is
      {:ok, %{items: &Nestru.decode_from_list(&1, FruitBox.Fruit)}}
    end
  end
end