JsonRemedy.Utils.CharUtils (json_remedy v0.1.3)

View Source

Optimized UTF-8 safe character navigation utilities for JSON parsing.

This module provides high-performance character-by-character navigation functions that handle Unicode characters correctly while maintaining excellent performance for JSON string processing. All functions use String.length/1 and String.at/2 for UTF-8 safety, avoiding byte-based operations that could break on multi-byte characters.

Performance Optimizations

  • Early bounds checking to avoid unnecessary computations
  • Optimized whitespace detection using compile-time constants
  • Tail-recursive functions for memory efficiency
  • Minimal pattern matching overhead
  • Reduced function call overhead in hot paths

Features

  • UTF-8 safe character positioning using grapheme-based counting
  • Comprehensive bounds checking with graceful error handling
  • Defensive programming patterns against nil and invalid inputs
  • Context-aware whitespace handling for JSON parsing scenarios
  • Performance-optimized for common character navigation tasks

Safety Guarantees

All functions in this module:

  • Handle nil inputs gracefully without raising exceptions
  • Use String.length/1 for character counting (not byte_size/1)
  • Use String.at/2 for character access (not binary pattern matching)
  • Return consistent result types for error conditions
  • Preserve UTF-8 character boundaries correctly

Examples

iex> JsonRemedy.Utils.CharUtils.get_char_at("café", 3, nil)
"é"

iex> JsonRemedy.Utils.CharUtils.skip_to_character("hello world", "w", 0)
6

iex> JsonRemedy.Utils.CharUtils.whitespace?(" ")
true

iex> JsonRemedy.Utils.CharUtils.char_at_position_safe("test", 10)
nil

Summary

Functions

Safe wrapper for String.at/2 that handles nil inputs gracefully.

Safely retrieves character at specified position with default fallback.

Searches for target character starting from given position.

Skips whitespace characters from start position up to end position.

Checks if a character is considered whitespace for JSON parsing.

Types

char_result()

@type char_result() :: String.t() | nil

position()

@type position() :: non_neg_integer()

search_result()

@type search_result() :: non_neg_integer() | nil

Functions

char_at_position_safe(input, position)

@spec char_at_position_safe(String.t() | nil, position()) :: char_result()

Safe wrapper for String.at/2 that handles nil inputs gracefully.

Optimized thin wrapper that leverages String.at/2's built-in bounds checking. Provides a safe way to access characters at specific positions without raising exceptions. Returns nil for any error condition.

Parameters

  • input - The input string (may be nil)
  • position - Zero-based character position (non-negative integer)

Returns

  • The character at the position if valid
  • nil if position is out of bounds, input is nil, or invalid parameters

Examples

iex> char_at_position_safe("hello", 1)
"e"

iex> char_at_position_safe("café", 3)
"é"

iex> char_at_position_safe("test", 10)
nil

iex> char_at_position_safe("", 0)
nil

iex> char_at_position_safe(nil, 0)
nil

get_char_at(input, position, default)

@spec get_char_at(String.t() | nil, position(), any()) :: any()

Safely retrieves character at specified position with default fallback.

Optimized for performance with early bounds checking and minimal overhead. Returns the character at the given position, or the default value if the position is out of bounds, the input is nil, or any other error condition occurs.

Parameters

  • input - The input string (may be nil)
  • position - Zero-based character position (non-negative integer)
  • default - Value to return if character cannot be retrieved

Returns

  • The character at the position if valid
  • The default value if position is out of bounds or input is nil/invalid

Examples

iex> get_char_at("hello", 0, nil)
"h"

iex> get_char_at("café", 3, nil)
"é"

iex> get_char_at("test", 10, "?")
"?"

iex> get_char_at(nil, 0, "default")
"default"

iex> get_char_at("", 0, nil)
nil

skip_to_character(input, target_char, start_pos)

@spec skip_to_character(String.t() | nil, String.t() | nil, position()) ::
  search_result()

Searches for target character starting from given position.

Optimized with early bounds checking and efficient search loop. Finds the first occurrence of the target character in the input string, starting the search from the specified position. Returns the position where the character was found, or nil if not found or invalid input.

Parameters

  • input - The input string to search (may be nil)
  • target_char - The character to search for (may be nil)
  • start_pos - Starting position for the search (non-negative integer)

Returns

  • Position (integer) where the character was found
  • nil if character not found, input is nil, or invalid parameters

Examples

iex> skip_to_character("hello world", "w", 0)
6

iex> skip_to_character("test", "s", 2)
2

iex> skip_to_character("café résumé", "é", 0)
3

iex> skip_to_character("hello", "x", 0)
nil

iex> skip_to_character(nil, "a", 0)
nil

skip_whitespaces_at(input, start_pos, end_pos)

@spec skip_whitespaces_at(String.t() | nil, position(), position()) :: position()

Skips whitespace characters from start position up to end position.

Highly optimized with compile-time whitespace constants and efficient loop. Advances through the input string starting from start_pos, skipping over whitespace characters until a non-whitespace character is found or end_pos is reached.

Parameters

  • input - The input string (may be nil)
  • start_pos - Starting position (non-negative integer)
  • end_pos - Maximum position to check (non-negative integer)

Returns

  • Position (integer) of first non-whitespace character or end_pos if all whitespace
  • start_pos if input is nil or invalid parameters

Examples

iex> skip_whitespaces_at("   hello", 0, 8)
3

iex> skip_whitespaces_at("hello", 0, 5)
0

iex> skip_whitespaces_at("  \t\n  test", 0, 12)
6

iex> skip_whitespaces_at("   ", 0, 3)
3

iex> skip_whitespaces_at(nil, 0, 5)
0

whitespace?(char)

@spec whitespace?(String.t() | nil) :: boolean()

Checks if a character is considered whitespace for JSON parsing.

Optimized with compile-time constant for maximum performance. Determines whether the given character should be treated as whitespace in the context of JSON parsing. Handles both ASCII and Unicode whitespace characters.

Parameters

  • char - The character to check (may be nil or non-string)

Returns

  • true if the character is whitespace
  • false if the character is not whitespace or is nil/invalid

Examples

iex> whitespace?(" ")
true

iex> whitespace?("\t")
true

iex> whitespace?("\n")
true

iex> whitespace?("\r")
true

iex> whitespace?("a")
false

iex> whitespace?(nil)
false

iex> whitespace?("")
false