NimbleOptionsEx (nimble_options_ex v0.2.0)

View Source

Set of custom functions to enhance the UX with NimbleOptions.

Summary

Functions

Validates that the term passed implements Access behaviour.

Validates a behaviour specified as a module or as a set of functions.

Validates that the term passed is a prop, a member of a prop_list.

Functions

access?(value)

@spec access?(term()) :: {:ok, validated_option :: module()} | {:error, String.t()}

Validates that the term passed implements Access behaviour.

Example:

iex> schema = [
...>   container: [
...>     required: true,
...>     type: {:custom, NimbleOptionsEx, :access?, []},
...>     doc: "The implementation of `Access` to be used as a storage"
...>   ]
...> ]
iex> NimbleOptions.validate([container: %{}], schema)
{:ok, [container: %{}]}
iex> NimbleOptions.validate([container: [foo: :bar]], schema)
{:ok, [container: [foo: :bar]]}
iex> NimbleOptions.validate([container: [1, 2, 3]], schema)
{:error, %NimbleOptions.ValidationError{
  message: "invalid value for :container option: expected a keyword list, got a list ‹[1, 2, 3]›",
  key: :container, value: [1, 2, 3], keys_path: []}}

behaviour(value, funs_or_behaviour \\ [])

@spec behaviour(module() | any(), module() | {module(), :strict} | []) ::
  {:ok, validated_option :: module()} | {:error, String.t()}

Validates a behaviour specified as a module or as a set of functions.

Example:

iex> schema = [
...>   container: [
...>     required: true,
...>     type: {:custom, NimbleOptionsEx, :behaviour, [Supervisor]},
...>     doc: "The implementation of `Supervisor` to be used as a supervisor"
...>   ]
...> ]
iex> NimbleOptions.validate([container: DynamicSupervisor], schema)
{:ok, [container: DynamicSupervisor]}
iex> NimbleOptions.validate([container: DateTime], schema)
{:error, %NimbleOptions.ValidationError{
  message: "invalid value for :container option: module ‹DateTime› does not implement requested callbacks ‹[init: 1]›",
  key: :container, value: DateTime, keys_path: []}}

If no arguments are given, the checker would make sure the module passed is indeed a module, available at the moment of invocation.


Please note, that Access behaviour is somewhat special, because it’s supported for terms, such as maps %{foo: :bar} (not Map,) keywords [foo: :bar] (not Keyword,) and structs %Strct{foo: :bar} (not Strct module itself.) Use access?/1 validator to check whether Access is supported by a term itself.

property(other, expected_type)

@spec property(term(), atom() | tuple() | keyword()) ::
  {:ok, validated_option :: module()} | {:error, String.t()}

Validates that the term passed is a prop, a member of a prop_list.

Example:

iex> schema = [
...>   prop: [
...>     required: true,
...>     type: {:custom, NimbleOptionsEx, :property, [:string]},
...>     doc: "The property of type `{atom(), binary()}`"
...>   ]
...> ]
iex> NimbleOptions.validate([prop: {:foo, "bar"}], schema)
{:ok, [prop: {:foo, "bar"}]}
iex> NimbleOptions.validate([prop: {:foo, 42}], schema)
{:error, %NimbleOptions.ValidationError{
    message: "invalid value for :prop option: invalid value for :foo option: expected string, got: 42",
    key: :prop, keys_path: [], value: {:foo, 42}}}