Current section

Files

Jump to
vela lib vela.ex
Raw

lib/vela.ex

defmodule Vela do
@moduledoc """
`Vela` is a tiny library providing easy management of
validated cached state with some history.
Including `use Vela` in your module would turn the module
into struct, setting field accordingly to the specification,
passed as a parameter.
`Vela` allows the following configurable parameters per field:
- length of the series to keep (default `5`)
- validation function as either module implementing `Vela.Validator`
behaviour, or a local function (default `fn _, _, _ -> true end`)
- timestamp extractor function to either extract the timestamp
from the underlying terms (default `&DateTime.utc_now/0`)
- number of errors to keep (default: `5`)
`Vela` implements `Access` behaviour.
## Usage
defmodule Vela.Test do
use Vela,
series1: [limit: 3, errors: 1], # no validation
series2: [limit: 2, validator: Vela.Test]
@behaviour Vela.Validator
@impl Vela.Validator
def valid?(%__MODULE__{} = state, key, value) do
value > 0
end
end
In the example above, before any structure update attempt
(via `Access`,) this `valid?/3` function would be called.
If it returns `true`, the value gets inserted / updated, and
the series behind is truncated if needed. It it returns `false`,
the state _is not updated_, and the value is put into the map
under `__errors__` key of the struct. The length of errors
is also configurable via `errors:` keyword parameter.
"""
@typedoc "Represents the struct created by this behaviour module"
@type t :: %{
:__struct__ => atom(),
:__errors__ => %{optional(atom) => [any()]},
:__meta__ => keyword(),
optional(atom()) => any()
}
@doc false
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
@fields Keyword.keys(opts)
@with_initials [{:__errors__, %{}} | Enum.zip(@fields, Stream.cycle([[]]))]
defstruct @with_initials
use Vela.Access, opts
end
end
end