defmodule QRNBU.Validators.FieldLock do
@moduledoc """
Validator for field lock bitmap.
Validates field lock values used to control which fields can be edited
in the payment application. Each bit represents a field's editability.
Accepts both integer values and `QRNBU.FieldLock` structs.
"""
alias QRNBU.FieldLock
@doc """
Validates field lock value.
## Rules
- Must be an integer or `QRNBU.FieldLock` struct
- Integer must be in range 0x0000 to 0xFFFF (0 to 65535)
## Examples
iex> QRNBU.Validators.FieldLock.validate(0x1234)
{:ok, 0x1234}
iex> QRNBU.Validators.FieldLock.validate(0)
{:ok, 0}
iex> QRNBU.Validators.FieldLock.validate(65535)
{:ok, 65535}
iex> QRNBU.Validators.FieldLock.validate(-1)
{:error, "Field lock must be between 0 and 65535"}
iex> QRNBU.Validators.FieldLock.validate(65536)
{:error, "Field lock must be between 0 and 65535"}
iex> QRNBU.Validators.FieldLock.validate("1234")
{:error, "Field lock must be an integer or FieldLock struct"}
iex> QRNBU.Validators.FieldLock.validate(QRNBU.FieldLock.all())
{:ok, 65535}
iex> QRNBU.Validators.FieldLock.validate(QRNBU.FieldLock.preset(:editable_amount))
{:ok, 65279}
"""
@spec validate(integer() | FieldLock.t()) :: {:ok, integer()} | {:error, String.t()}
def validate(%FieldLock{} = field_lock) do
{:ok, FieldLock.to_integer(field_lock)}
end
def validate(lock) when is_integer(lock) do
if lock >= 0 and lock <= 0xFFFF do
{:ok, lock}
else
{:error, "Field lock must be between 0 and 65535"}
end
end
def validate(_), do: {:error, "Field lock must be an integer or FieldLock struct"}
end