JsonRemedy.Context.JsonContext (json_remedy v0.1.3)

View Source

Centralized context tracking for JSON repair operations.

This module provides state management for tracking the current parsing context, which enables context-aware repair decisions across all layers. It tracks whether we're in an object key, object value, array, or string context.

Summary

Functions

Determines if a repair can be applied in the current context.

Returns the depth of the context stack.

Enters string parsing context with the given delimiter.

Exits string parsing context.

Checks if the context is currently inside a string.

Creates a new empty context with default values.

Pops the most recent context from the stack.

Pushes a new context onto the context stack.

Transitions from the current context to a new context.

Updates the current position in the input string.

Types

context_value()

@type context_value() :: :root | :object_key | :object_value | :array

t()

@type t() :: %JsonRemedy.Context.JsonContext{
  current: context_value(),
  in_string: boolean(),
  position: non_neg_integer(),
  stack: [context_value()],
  string_delimiter: String.t() | nil
}

Functions

can_apply_repair?(json_context, arg2)

@spec can_apply_repair?(t(), atom()) :: boolean()

Determines if a repair can be applied in the current context.

String delimiter repairs are allowed when in strings, but most other repairs should be avoided to prevent corrupting string content.

Examples

iex> context = JsonRemedy.Context.JsonContext.new()
iex> JsonRemedy.Context.JsonContext.can_apply_repair?(context, :quote_normalization)
true

iex> string_context = JsonRemedy.Context.JsonContext.enter_string(context, "\"")
iex> JsonRemedy.Context.JsonContext.can_apply_repair?(string_context, :quote_normalization)
false
iex> JsonRemedy.Context.JsonContext.can_apply_repair?(string_context, :string_delimiter)
true

context_stack_depth(json_context)

@spec context_stack_depth(t()) :: non_neg_integer()

Returns the depth of the context stack.

Examples

iex> context = JsonRemedy.Context.JsonContext.new()
iex> JsonRemedy.Context.JsonContext.context_stack_depth(context)
0

iex> nested = %JsonRemedy.Context.JsonContext{stack: [:root, :array]}
iex> JsonRemedy.Context.JsonContext.context_stack_depth(nested)
2

enter_string(context, delimiter)

@spec enter_string(t(), String.t()) :: t()

Enters string parsing context with the given delimiter.

Examples

iex> context = JsonRemedy.Context.JsonContext.new()
iex> string_context = JsonRemedy.Context.JsonContext.enter_string(context, "\"")
iex> string_context.in_string
true
iex> string_context.string_delimiter
"\""

exit_string(context)

@spec exit_string(t()) :: t()

Exits string parsing context.

Examples

iex> context = %JsonRemedy.Context.JsonContext{in_string: true, string_delimiter: "\""}
iex> exited = JsonRemedy.Context.JsonContext.exit_string(context)
iex> exited.in_string
false
iex> exited.string_delimiter
nil

is_in_string?(json_context)

@spec is_in_string?(t()) :: boolean()

Checks if the context is currently inside a string.

Examples

iex> context = JsonRemedy.Context.JsonContext.new()
iex> JsonRemedy.Context.JsonContext.is_in_string?(context)
false

iex> string_context = JsonRemedy.Context.JsonContext.enter_string(context, "\"")
iex> JsonRemedy.Context.JsonContext.is_in_string?(string_context)
true

new()

@spec new() :: %JsonRemedy.Context.JsonContext{
  current: :root,
  in_string: false,
  position: 0,
  stack: [],
  string_delimiter: nil
}

Creates a new empty context with default values.

Examples

iex> context = JsonRemedy.Context.JsonContext.new()
iex> context.current
:root
iex> context.stack
[]
iex> context.position
0
iex> context.in_string
false

pop_context(context)

@spec pop_context(t()) :: t()

Pops the most recent context from the stack.

If the stack is empty, the context remains unchanged.

Examples

iex> context = %JsonRemedy.Context.JsonContext{current: :object_key, stack: [:root]}
iex> popped = JsonRemedy.Context.JsonContext.pop_context(context)
iex> popped.current
:root
iex> popped.stack
[]

push_context(context, new_context)

@spec push_context(t(), context_value()) :: t()

Pushes a new context onto the context stack.

The current context becomes the new context and the previous current context is pushed onto the stack.

Examples

iex> context = JsonRemedy.Context.JsonContext.new()
iex> new_context = JsonRemedy.Context.JsonContext.push_context(context, :object_key)
iex> new_context.current
:object_key
iex> new_context.stack
[:root]

transition_context(context, new_context)

@spec transition_context(t(), context_value()) :: t()

Transitions from the current context to a new context.

Unlike push_context/2, this doesn't modify the stack.

Examples

iex> context = %JsonRemedy.Context.JsonContext{current: :object_key}
iex> transitioned = JsonRemedy.Context.JsonContext.transition_context(context, :object_value)
iex> transitioned.current
:object_value

update_position(context, position)

@spec update_position(t(), non_neg_integer()) :: t()

Updates the current position in the input string.

Examples

iex> context = JsonRemedy.Context.JsonContext.new()
iex> updated = JsonRemedy.Context.JsonContext.update_position(context, 15)
iex> updated.position
15