ex_structable v0.4.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 \\ []) # ...
@docs 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
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/0for 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.
# NOTE: Currently doesn't work on ExConstructor because library is broken
strict_keys: true
]