Nestru.Decoder protocol (Nestru v0.1.0) View Source
Link to this section Summary
Functions
Returns the hint of how to decode the struct fields.
Link to this section Types
Specs
t() :: term()
Link to this section Functions
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.from_map/3
function call.
The third argument is a map to be decoded into the struct. The map is useful to generate a hint for fields that have a dynamic struct type.
If the function returns {:ok, map}
then the map
's key-value pairs specify
the decoding hint for a field with the key name and the value configuring the following:
A module's atom 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.
An anonymous function with arity 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 expected to return
{:ok, term}
,{:error, %{message: term, path: list}}
, or{:error, term}
.
Any field missing the key in the map
receives the value as-is.
The %{}
empty map
value defines that all fields of the
struct take all values from the second argument's map unmodified.
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,
automatically set the @derive module
attribute to the tuple of Elixir.Nestru.Decoder
and the map
to be returned.
Examples
defmodule FruitBox do
defstruct [:items]
# Give a function to decode the list field as a hint
defimpl Nestru.Decoder do
def from_map_hint(_value, _context, map) do
{:ok, %{items: &Nestru.from_list_of_maps(&1, FruitBox.Fruit)}}
end
end
end
# Generate implementation by deriving the protocol
def FruitBox.Fruit do
@derive {
Nestru.Decoder,
%{
vitamins: &__MODULE__.decode_vitamins/1,
energy: FruitEnergy
}
}
def decode_vitamins(value), do: Nestru.from_list_of_maps(value, Vitamin)
defstruct [:vitamins, :energy]
end