Starchoice.Decoder behaviour (starchoice v0.2.1) View Source
This module can be used from two different ways:
As a macro
To be defining decoders as macro, you need to use the Starchoice.Decoder
module in your struct. It's declaration is highly (like totally) inspired by Ecto's schemas.
To see available options, take a look at put_field/3
's documentation
Examples
defmodule User do
use Starchoice.Decoder
defstruct first_name: nil, age: nil
defdecoder do
field(:first_name)
field(:age)
end
end
User.__decoder__() # %Decoder{}
User.__decoder__(:default) # %Decoder{}
When you don't pass a name to the defdecoder/2
function, it defaults to default
. So calling defdecoder do
and defdecoder :default do
is identical. This is because you might be interested in creating multiple decoders for the same struct like below:
defmodule User do
use Starchoice.Decoder
defstruct first_name: nil, last_name: nil, email: nil, age: nil
defdecoder do
field(:first_name)
field(:age)
end
defdecoder :full do
field(:first_name)
field(:last_name)
field(:email)
field(:age)
end
end
User.__decoder__() # %Decoder{fields: [{:first_name, _}, {:age, _}]}
User.__decoder__(:default) # %Decoder{fields: [{:first_name, _}, {:age, _}]}
User.__decoder__(:full) # %Decoder{fields: [{:first_name, _}, {:last_name, _}, {:email, _}, {:age, _}]}
And you can now use the module directly when calling Starchoice.decode/3
like:
iex> Starchoice.decode(input, User)
iex> Starchoice.decode(input, {User, :full})
Manually
You could also build decoder manually like the following:
defmodule User do
defstruct email: nil, password: nil
def mask_password(_), do: "MASKED"
end
User
|> Decoder.new()
|> Decoder.put_field(:email)
|> Decoder.put_field(:password, with: &User.mask_password/1)
# or
Decoder.new(User, [
{:email, []},
{:password, with: &User.mask_password/1}
])
To see available options, take a look at put_field/3
's documentation
Link to this section Summary
Functions
Initiates a new Decoder, you can pass a list of fields with options.
Puts a field decoding in the decoder. Available options are
Link to this section Types
Specs
decoder_struct() :: module() | :map
Specs
field_definition() :: {atom(), [field_option()]}
Specs
field_option() :: {:required, boolean()} | {:with, Starchoice.decoder()} | {:default, any()} | {:sanitize, function()} | {:source, String.t()}
Specs
t() :: %Starchoice.Decoder{fields: [field_definition()], struct: module()}
Link to this section Functions
Specs
Specs
field(atom(), [field_option()]) :: Macro.t()
Specs
new(decoder_struct(), [field_definition()]) :: t()
Initiates a new Decoder, you can pass a list of fields with options.
To see available options, take a look at put_field/3
's documentation
Specs
put_field(t(), atom(), [field_option()]) :: t()
Puts a field decoding in the decoder. Available options are:
:required
: Defines if a field is required, will caused a raise (or{:error, _}
tuple) when the required field isn't present:default
: Specifies a fallback value in case the field is missing (can't be used withrequired: true
):with
: Specifies a decoder the decode the given field. Like theStarchoice.decode/3
call, it can support any valid decoder inModule
,{Module, :decoder}
and a function.:sanitize
: Specifies a sanitizer. By default, the value is sanitized by trimming the value and casting to nil if the value is "". Can either be a boolean or a function.:source
: Specifies the source key in the decoding item