Raxol.Core.Utils.Validation (Raxol Core v2.8.0)

Copy Markdown View Source

Common validation utilities to reduce code duplication across the codebase. Provides standardized validation functions for dimensions, configs, and common patterns.

Summary

Types

A terminal size ceiling: largest width, height and width * height.

Functions

Validates that a value is within specified bounds.

Validates a configuration map against required keys.

Validates that coordinates are valid non-negative integers.

Validates that a dimension is a positive integer, returning default if invalid.

Validates that a value is one of the allowed options.

Validates that a list contains only specific types.

Validates that a string is not empty and optionally matches a pattern.

Checks a terminal size against the ceiling clamp_terminal_size/3 applies, by default the local one.

Types

terminal_size_ceiling()

@type terminal_size_ceiling() :: %{
  width: pos_integer(),
  height: pos_integer(),
  cells: pos_integer()
}

A terminal size ceiling: largest width, height and width * height.

Functions

clamp_terminal_size(width, height, map \\ Defaults.terminal_size_ceiling())

@spec clamp_terminal_size(term(), term(), terminal_size_ceiling()) :: {term(), term()}

Clamps a terminal size to a ceiling, by default the local one, Raxol.Core.Defaults.terminal_size_ceiling/0. Network surfaces pass Raxol.Core.Defaults.remote_terminal_size_ceiling/0 (or their own).

The width is capped at the ceiling's :width, then the height at its :height and at as many rows as its :cells allows at that width, so width * height never exceeds the cell ceiling. Only the upper bound is applied: a size already within the ceiling, and a non-positive or non-integer value, comes back unchanged.

iex> Raxol.Core.Utils.Validation.clamp_terminal_size(120, 40)
{120, 40}

iex> Raxol.Core.Utils.Validation.clamp_terminal_size(100_000, 100_000)
{4096, 256}

iex> Raxol.Core.Utils.Validation.clamp_terminal_size(
...>   100_000,
...>   100_000,
...>   Raxol.Core.Defaults.remote_terminal_size_ceiling()
...> )
{512, 256}

validate_bounds(value, min, max)

@spec validate_bounds(number(), number(), number()) ::
  {:ok, number()} | {:error, :out_of_bounds}

Validates that a value is within specified bounds.

validate_config(config, required_keys)

@spec validate_config(map(), [atom()]) ::
  {:ok, map()} | {:error, {:missing_keys, [atom()]}}

Validates a configuration map against required keys.

validate_coordinates(x, y)

@spec validate_coordinates(integer(), integer()) ::
  {:ok, {non_neg_integer(), non_neg_integer()}} | {:error, :invalid_coordinates}

Validates that coordinates are valid non-negative integers.

validate_dimension(dimension, default)

@spec validate_dimension(integer(), non_neg_integer()) :: non_neg_integer()

Validates that a dimension is a positive integer, returning default if invalid.

It sets no upper bound; a terminal width or height goes through clamp_terminal_size/2 or validate_terminal_size/2 as well.

validate_enum(value, allowed)

@spec validate_enum(any(), list()) :: {:ok, any()} | {:error, :invalid_option}

Validates that a value is one of the allowed options.

validate_list_types(list, type)

@spec validate_list_types(list(), atom()) :: {:ok, list()} | {:error, :invalid_types}

Validates that a list contains only specific types.

validate_string(str, pattern \\ nil)

@spec validate_string(binary(), Regex.t() | nil) ::
  {:ok, binary()} | {:error, :invalid_string}

Validates that a string is not empty and optionally matches a pattern.

validate_terminal_size(width, height, ceiling \\ Defaults.terminal_size_ceiling())

@spec validate_terminal_size(term(), term(), terminal_size_ceiling()) ::
  :ok | {:error, :invalid_dimensions | :dimensions_too_large}

Checks a terminal size against the ceiling clamp_terminal_size/3 applies, by default the local one.

Returns {:error, :invalid_dimensions} unless both are positive integers, and {:error, :dimensions_too_large} when either axis, or width * height, is past the ceiling.