Localize.Inputs.Number.Validator (Localize.Inputs.Number v0.1.1)

Copy Markdown View Source

Server-side validation for parsed number values.

Pure Elixir, no Ecto dependency. The Ecto changeset bridge is in Localize.Inputs.Number.Changeset.

Summary

Functions

Validates a parsed number against bounds, precision, and required-ness.

Validates a unit-of-measure form submission.

Functions

validate_number(value, options \\ [])

@spec validate_number(term(), Keyword.t()) ::
  :ok | {:error, Localize.Inputs.ValidationError.t()}

Validates a parsed number against bounds, precision, and required-ness.

Arguments

  • value is a Decimal, integer, or nil.

  • options is a keyword list of options.

Options

  • :required — when true, nil is rejected.

  • :min — minimum allowed value (any numeric form the parser accepts).

  • :max — maximum allowed value.

  • :decimals — maximum number of fractional digits.

Returns

  • :ok when every check passes.

  • {:error, %Localize.Inputs.ValidationError{errors: [{atom(), String.t()}]}} with one entry per failing check, in the order :required, :min, :max, :decimals. Localize.Inputs.Number.Changeset.validate_number/3 unpacks the entries into per-field changeset errors.

Examples

iex> Localize.Inputs.Number.Validator.validate_number(Decimal.new("5"), min: 1, max: 10)
:ok

iex> {:error, %Localize.Inputs.ValidationError{errors: errors}} =
...>   Localize.Inputs.Number.Validator.validate_number(Decimal.new("15"), max: 10)
iex> errors
[{:max, "must be at most 10"}]

iex> {:error, %Localize.Inputs.ValidationError{errors: errors}} =
...>   Localize.Inputs.Number.Validator.validate_number(nil, required: true)
iex> errors
[{:required, "is required"}]

validate_unit(value, options \\ [])

@spec validate_unit(term(), Keyword.t()) ::
  :ok | {:error, Localize.Inputs.ValidationError.t()}

Validates a unit-of-measure form submission.

Accepts the %{"amount" => ..., "unit" => ...} map shape that Localize.Inputs.Number.Components.unit_input/1 submits. Checks that the amount passes validate_number/2 and that the unit is a known unit in the given category.

Arguments

  • value — a %{"amount", "unit"} map (string or atom keys), a bare numeric value, nil, or "".

  • options is a keyword list of options.

Options

Returns

  • :ok on success.

  • {:error, ValidationError.t()} on any failure — combined amount-validation errors plus a {:unit, "..."} error if the unit is missing or not in the category.

Examples

iex> Localize.Inputs.Number.Validator.validate_unit(
...>   %{"amount" => Decimal.new("1.75"), "unit" => "meter"},
...>   category: "length"
...> )
:ok

iex> {:error, %Localize.Inputs.ValidationError{errors: errors}} =
...>   Localize.Inputs.Number.Validator.validate_unit(
...>     %{"amount" => Decimal.new("1.75"), "unit" => "bogon"},
...>     category: "length"
...>   )
iex> Keyword.get(errors, :unit) =~ "bogon"
true

iex> {:error, %Localize.Inputs.ValidationError{errors: errors}} =
...>   Localize.Inputs.Number.Validator.validate_unit(
...>     %{"amount" => Decimal.new("70"), "unit" => "kilogram"},
...>     category: "length"
...>   )
iex> Keyword.get(errors, :unit) =~ "mass"
true