Erabi.Rules (Erabi v0.1.0)

Copy Markdown View Source

What a picker accepts: the same rules in the browser, as people choose, and on the server, in Erabi.Changeset.

@rules Erabi.Rules.new(max: 3, create: true, max_length: 24)

<.tags field={@form[:labels]} options={@labels} rules={@rules} />

changeset
|> cast(params, [:labels])
|> Erabi.Changeset.validate_choice(:labels, @rules, options: @labels)

The rules:

  • :required - at least one value;
  • :min, :max - how many values, for a picker of several;
  • :create - whether a value that is not an option may be chosen (typed, as a new tag, or kept as text in a combobox); without it, every value must be an option;
  • :min_length, :max_length - the length of a new value, in characters (graphemes);
  • :pattern - a regular expression a new value must match, whole. It runs in the browser too (RegExp with the u flag), so keep to what both have: classes, ranges, \d, \w, \s, \p{L}, counts and alternatives.

A picker of several never posts the same value twice.

The browser checks the rules as people choose: it does not add a value past :max, and says why it cannot create a value. The server checks them again: the browser is a convenience, and a form can be posted by anything.

Summary

Types

Why values are refused, with what the message needs

t()

Functions

Checks the values that a picker posts (texts, see Erabi.Option.params/1) against the rules: :ok, or the first reason they are refused. known is the values of the options, or :any when the options are not all known here (a search): then values are not refused for not being options.

Checks a value that is not an option, as a person creates it: :ok, or why it cannot be.

Rules from a keyword list (see the moduledoc), or the rules as they are. Raises an ArgumentError that says what is wrong.

Types

error()

@type error() :: {atom(), keyword()}

Why values are refused, with what the message needs:

  • {:required, []}
  • {:too_few, min: n}, {:too_many, max: n}
  • {:not_allowed, value: v} - not an option, and :create is off
  • {:too_short, min_length: n, value: v}, {:too_long, max_length: n, value: v}
  • {:format, value: v} - a new value that does not match :pattern
  • {:duplicate, value: v}

t()

@type t() :: %Erabi.Rules{
  create: boolean(),
  max: pos_integer() | nil,
  max_length: pos_integer() | nil,
  min: non_neg_integer() | nil,
  min_length: non_neg_integer() | nil,
  pattern: String.t() | nil,
  required: boolean()
}

Functions

check(rules, values, known)

@spec check(t(), [String.t()], [String.t()] | :any) :: :ok | {:error, error()}

Checks the values that a picker posts (texts, see Erabi.Option.params/1) against the rules: :ok, or the first reason they are refused. known is the values of the options, or :any when the options are not all known here (a search): then values are not refused for not being options.

iex> rules = Erabi.Rules.new(max: 2)
iex> Erabi.Rules.check(rules, ["a", "b", "c"], ["a", "b", "c"])
{:error, {:too_many, [max: 2]}}
iex> Erabi.Rules.check(rules, ["x"], ["a", "b"])
{:error, {:not_allowed, [value: "x"]}}

check_value(rules, value)

@spec check_value(t(), String.t()) :: :ok | {:error, error()}

Checks a value that is not an option, as a person creates it: :ok, or why it cannot be.

iex> Erabi.Rules.check_value(Erabi.Rules.new(create: true, max_length: 3), "four")
{:error, {:too_long, [max_length: 3, value: "four"]}}

new(rules)

@spec new(t() | keyword() | nil) :: t()

Rules from a keyword list (see the moduledoc), or the rules as they are. Raises an ArgumentError that says what is wrong.

iex> Erabi.Rules.new(max: 3)
%Erabi.Rules{max: 3}