ex_structable v0.3.0 ExStructable View Source
The use
-able module.
These methods are added to the module that has use ExStructable
:
def new(args, override_opts \\ []) # ...
def put(struct = %_{}, args, override_opts \\ []) # ...
@doc
s are added to your module for the above methods. Run mix doc
to
see them.
Example usage:
iex> defmodule Line do
...> @enforce_keys [:length, :x, :y]
...> defstruct [:length, :x, :y]
...>
...> use ExStructable # Adds `new` and `put` dynamically
...>
...> # Optional hook
...> @impl true
...> def validate_struct(line, _options) do
...> if line.length <= 0 do
...> raise ArgumentError, "Invalid length found"
...> end
...>
...> line
...> end
...> end
...>
...> Line.new(length: 1, x: 1, y: 2) |> inspect()
"%ExStructableTest.Line{length: 1, x: 1, y: 2}"
And new
fails when validate_struct/2
fails:
...> Line.new(length: -2, x: 1, y: 2)
** (ArgumentError) Invalid length found
Here is an example of the put
method usage:
...> Line.new(length: 1, x: 1, y: 2) |> Line.put(length: 3) |> inspect()
"%ExStructableTest.Line{length: 3, x: 1, y: 2}"
And put
method validation failure:
...> Line.new(length: 1, x: 1, y: 2) |> Line.put(length: -3, x: 2)
** (ArgumentError) Invalid length found
Configuration
Options
The use
macro has optional arguments. See __using__/1
.
You can even pass these options to the new
and put
methods:
...> Line.new([length: -3, x: 1, y: 2], [validate_struct: false])
"%ExStructableTest.Line{length: -3, x: 1, y: 2}"
Hooks
For more optional hooks like validate_struct/2
(see ExStructable.Hooks
).
ExConstructor Integration
You can use ExConstructor at the
same time using use_ex_constructor_library: true
:
iex> defmodule Line2 do
...> defstruct [:length_in_cm, :x, :y]
...>
...> use ExStructable, use_ex_constructor_library: true
...>
...> @impl true
...> def validate_struct(line, _options) do
...> if line.length_in_cm <= 0 do
...> raise ArgumentError, "Invalid length found"
...> end
...>
...> line
...> end
...> end
...>
...> # We can now pass camelcase arguments
...> Line2.new(lengthInCm: 1, x: 1, y: 2) |> inspect()
"%ExStructableTest.Line2{length_in_cm: 1, x: 1, y: 2}"
And validation still fails as expected:
...> Line2.new(lengthInCm: -3, x: 1, y: 2) |> inspect()
** (ArgumentError) Invalid length found
(Do not put use ExConstructor
as that is added to your module when the
option use_ex_constructor_library
is set to a truthy value).
If you want to pass args to ExConstructor
:
use ExStructable, use_ex_constructor_library: [
# args for `use ExConstructor` here
]
Link to this section Summary
Types
Key value pairs to put into the struct
Options passed to use ExStructable
, new
, and put
Usually is a struct, may not be if validate_struct/2 is overriden and returns something else
Functions
Add new
and put
functions to the caller’s module
The doctest below shows the default values of the of the possible use
and
override_opts
, and their descriptions
Link to this section Types
args() :: keyword() | %{required(atom() | String.t()) => any()}
Key value pairs to put into the struct.
Options passed to use ExStructable
, new
, and put
.
Usually is a struct, may not be if validate_struct/2 is overriden and returns something else.
Link to this section Functions
Add new
and put
functions to the caller’s module.
- options - (Keyword List) See
default_options/0
for more all possible options.
The doctest below shows the default values of the of the possible use
and
override_opts
, and their descriptions.
iex> default_options()
[
# Call validate_struct callback?
validate_struct: true,
# Use library https://github.com/appcues/exconstructor .
# Is a boolean or Keyword List of options to be passed to
# `use ExConstructor`.
use_ex_constructor_library: false,
# The name of the `new` function to define in your module.
new_function_name: :new,
# The name of the `put` function to define in your module.
put_function_name: :put,
# Throw KeyError on passing unknown key, and
# throw ArgumentError if a key from `@enforce_keys` is missing.
strict_keys: true
]