Module: Hitch::MCP::Internal::JsonValues
- Defined in:
- app/models/hitch/mcp/internal/json_values.rb
Overview
Shared recursive helpers for the JSON-value structures that cross MCP boundaries. Keys are never symbolized (INV-MCP-007).
Defined Under Namespace
Classes: Copier
Constant Summary collapse
- DEFAULT_HANDLER =
Every rejecting boundary supplies its own on_invalid; this fires only when a policy rejects without one.
lambda do |reason, _detail| raise ArgumentError, "JSON value copy rejected (#{reason})" end
Class Method Summary collapse
-
.copy(value, keys: :as_is, symbols: :keep, foreign: :keep, finite: false, duplicates: :replace, freeze: false, max_depth: nil, max_objects: nil, on_invalid: DEFAULT_HANDLER) ⇒ Object
The one deep JSON copier.
- .deep_freeze(value) ⇒ Object
- .deep_string_copy_and_freeze(value) ⇒ Object
-
.read(hash, key) ⇒ Object
String/Symbol-indifferent read that prefers the key exactly as given.
Class Method Details
.copy(value, keys: :as_is, symbols: :keep, foreign: :keep, finite: false, duplicates: :replace, freeze: false, max_depth: nil, max_objects: nil, on_invalid: DEFAULT_HANDLER) ⇒ Object
The one deep JSON copier. Each boundary states its policy:
keys: :as_is, :string (String only), :stringify_symbols,
:preserve (String copied, Symbol kept), or :to_s
symbols: Symbol values — :keep, :to_s, or :reject
foreign: values outside the JSON universe — :keep, :to_s, or :reject
finite: reject non-finite Floats
duplicates: keys that collide after normalization — :replace or :reject
freeze: deep-freeze the copy
max_depth / max_objects: structural caps
on_invalid receives (reason, detail) and either raises or returns the replacement for the entire copy. Reasons: :recursive, :depth, :objects, :key, :duplicate_key, :non_finite, :foreign.
39 40 41 42 43 44 45 46 |
# File 'app/models/hitch/mcp/internal/json_values.rb', line 39 def copy(value, keys: :as_is, symbols: :keep, foreign: :keep, finite: false, duplicates: :replace, freeze: false, max_depth: nil, max_objects: nil, on_invalid: DEFAULT_HANDLER) Copier.new( keys:, symbols:, foreign:, finite:, duplicates:, freeze:, max_depth:, max_objects:, on_invalid: ).call(value) end |
.deep_freeze(value) ⇒ Object
52 53 54 55 56 57 58 59 60 |
# File 'app/models/hitch/mcp/internal/json_values.rb', line 52 def deep_freeze(value) case value when Hash value.each { |key, child| deep_freeze(key); deep_freeze(child) } when Array value.each { |child| deep_freeze(child) } end value.freeze end |
.deep_string_copy_and_freeze(value) ⇒ Object
48 49 50 |
# File 'app/models/hitch/mcp/internal/json_values.rb', line 48 def deep_string_copy_and_freeze(value) copy(value, keys: :to_s, freeze: true) end |
.read(hash, key) ⇒ Object
String/Symbol-indifferent read that prefers the key exactly as given.
20 21 22 23 24 25 |
# File 'app/models/hitch/mcp/internal/json_values.rb', line 20 def read(hash, key) return unless hash.is_a?(Hash) return hash[key] if hash.key?(key) hash[key.is_a?(Symbol) ? key.to_s : key.to_sym] end |