Croma.Struct
Utility module to define structs and some helper functions.
Using this module requires to prepare modules that represent each struct field. Each of per-field module must provide the following members:
- required:
@type t - required:
@spec validate(term) :: Croma.Result.t(t) - optional:
@spec default :: t
Some helpers for defining such per-field modules are available.
- Wrappers of built-in types such as
Croma.String,Croma.Integer, etc. - Utility modules such as
Croma.SubtypeOfStringto define “subtypes” of existing types. - Ad-hoc module generators defined in
Croma.TypeGen.
To define a struct, use this module with a keyword list:
defmodule S do
use Croma.Struct, field1_name: Field1Module, field2_name: Field2Module
end
Then the above code is converted to defstruct along with @type t.
This module also generates the following functions.
@spec new(Dict.t) :: Croma.Result.t(t)@spec new!(Dict.t) :: t@spec validate(term) :: Croma.Result.t(t)@spec validate!(term) :: t@spec update(t, Dict.t) :: Croma.Result.t(t)@spec update!(t, Dict.t) :: t
Examples
iex> defmodule I do
...> @type t :: integer
...> def validate(i) when is_integer(i), do: {:ok, i}
...> def validate(_), do: {:error, {:invalid_value, [__MODULE__]}}
...> def default, do: 0
...> end
...> defmodule S do
...> use Croma.Struct, i: I
...> end
...> S.validate([i: 5])
...> {:ok, %S{i: 5}}
...> S.validate(%{i: "not_an_integer"})
...> {:error, {:invalid_value, [S, I]}}
...> {:ok, s} = S.new([])
...> {:ok, %S{i: 0}}
...> S.update(s, [i: 2])
...> {:ok, %S{i: 2}}
...> S.update(s, %{"i" => "not_an_integer"})
...> {:error, {:invalid_value, [S, I]}}