lib/qr_nbu/validators/function_code.ex

defmodule QRNBU.Validators.FunctionCode do
  @moduledoc """
  Validator for payment function codes.

  Validates function codes that specify the type of payment transaction.
  """

  @valid_functions [:uct, :ict, :xct]

  @doc """
  Validates function code.

  ## Valid Codes
  - `:uct` - Ukrainian Credit Transfer (default)
  - `:ict` - International Credit Transfer
  - `:xct` - Cross-border Credit Transfer

  ## Examples

      iex> QRNBU.Validators.FunctionCode.validate(:uct)
      {:ok, :uct}

      iex> QRNBU.Validators.FunctionCode.validate(:ict)
      {:ok, :ict}

      iex> QRNBU.Validators.FunctionCode.validate(:xct)
      {:ok, :xct}

      iex> QRNBU.Validators.FunctionCode.validate(:invalid)
      {:error, "Invalid function code. Must be one of: uct, ict, xct"}

      iex> QRNBU.Validators.FunctionCode.validate("uct")
      {:error, "Function code must be an atom"}
  """
  @spec validate(atom()) :: {:ok, atom()} | {:error, String.t()}
  def validate(function) when is_atom(function) do
    if function in @valid_functions do
      {:ok, function}
    else
      {:error, "Invalid function code. Must be one of: #{Enum.join(@valid_functions, ", ")}"}
    end
  end

  def validate(_), do: {:error, "Function code must be an atom"}

  @doc """
  Returns list of valid function codes.
  """
  @spec valid_functions() :: [atom()]
  def valid_functions, do: @valid_functions
end