Reduce boilerplate by generating struct new
and put
functions,
and validate your structs when they are created and updated.
Optionally uses ExConstructor to "make it easier to instantiate struts from external data".
The package can be installed by adding ex_structable
to your list of
dependencies in mix.exs
:
def deps do
[
{:ex_structable, "~> 0.3.0"},
]
end
If you want to write some validation for your struct, you need to write the
boilerplate new
and put
methods manually.
defmodule Point do
@enforce_keys [:x, :y]
defstruct [:x, :y, :z]
def new(args) do
args = Keyword.new(args)
__MODULE__
|> Kernel.struct!(args)
|> validate_struct()
end
def put(struct, args) do
args = Keyword.new(args)
struct
|> Kernel.struct!(args)
|> validate_struct()
end
def validate_struct(struct) do
if struct.x < 0 or struct.y < 0 or struct.z < 0 do
raise ArgumentError
end
struct
end
end
Point.new(x: 1, y: 2)
# => %Point{x: 1, y: 2, z: nil}
Point.new(x: -1, y: 2)
# Fails validation, as expected
And you have to write this boilerplate for every module you have! That can be a lot of boilerplate!
By the magic of Elixir macros, we can remove the boilerplate!
defmodule Point do
@enforce_keys [:x, :y]
defstruct [:x, :y, :z]
use ExStructable # Adds `new` and `put` dynamically
# Optional hook
@impl true
def validate_struct(struct, _options) do
if struct.x < 0 or struct.y < 0 or struct.z < 0 do
raise ArgumentError
end
struct
end
end
Point.new(x: 1, y: 2)
# => %Point{x: 1, y: 2, z: nil} # Still works!
Point.new(x: -1, y: 2)
# Fails validation, as expected
And if you don't need validation yet, you might want to still add new
and
put
methods to be consistent (or to make it easier to add validation later).
In that case, you can just leave out the validate_struct/2
implementation.
defmodule Point do
@enforce_keys [:x, :y]
defstruct [:x, :y, :z]
use ExStructable # Adds `new` and `put` dynamically
end
For more detailed API documentation, see HexDocs.
Pull requests are welcomed! Please do discuss suggestions in an issue before implementing them.
git checkout master
- Make sure tests pass
mix test
- Update version in
mix.exs
- Ensure your user has been registered
mix hex.user register
- Run
mix hex.publish
(see for more information https://hex.pm/docs/publish) git tag <VERSION>
git push origin <VERSION>