Class: CoreLibrary::JsonPointer

Inherits:
Object
  • Object
show all
Defined in:
lib/apimatic-core/utilities/json_pointer.rb

Overview

The ‘JsonPointer` class provides a utility for querying, modifying, and deleting values within deeply nested Ruby Hashes and Arrays using JSON Pointer syntax (RFC 6901), extended with support for wildcards (`~`) and array-push semantics (`-`).

## Features

  • Navigate and retrieve deeply nested values using JSON Pointer paths.

  • Supports complex structures containing both Arrays and Hashes.

  • Wildcard support (‘~`) for batch operations across multiple elements.

  • Special key (‘-`) for appending to arrays (push behavior).

  • Optional ‘:symbolize_keys` behavior to convert pointer fragments to symbols.

## Example Usage

data = { "a" => [{ "b" => 1 }, { "b" => 2 }] }
pointer = JsonPointer.new(data, "/a/~1/b")
value = pointer.value  # => 2

pointer.value = 42
pointer.delete

## Limitations

  • This class operates directly on mutable input data structures.

  • Wildcards and array push keys are not part of the official JSON Pointer spec.

Examples:

Initialize and read value

JsonPointer.new({ "foo" => { "bar" => 42 } }, "/foo/bar").value # => 42

Constant Summary collapse

NotFound =
Class.new
WILDCARD =
'~'.freeze
ARRAY_PUSH_KEY =
'-'.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hash, path, options = {}) ⇒ JsonPointer

Returns a new instance of JsonPointer.



47
48
49
50
51
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 47

def initialize(hash, path, options = {})
  @hash = hash
  @path = path
  @options = options
end

Class Method Details

.escape_fragment(fragment) ⇒ Object



33
34
35
36
37
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 33

def self.escape_fragment(fragment)
  return fragment if fragment == WILDCARD

  fragment.gsub(/~/, '~0').gsub(%r{/}, '~1')
end

.join_fragments(fragments) ⇒ Object



43
44
45
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 43

def self.join_fragments(fragments)
  fragments.map { |f| escape_fragment(f) }.join('/')
end

.unescape_fragment(fragment) ⇒ Object



39
40
41
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 39

def self.unescape_fragment(fragment)
  fragment.gsub(/~1/, '/').gsub(/~0/, '~')
end

Instance Method Details

#deleteObject



61
62
63
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 61

def delete
  delete_member
end

#exists?Boolean

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
74
75
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 65

def exists?
  _exists = false
  get_target_member(@hash, path_fragments.dup) do |target, options = {}|
    if options[:wildcard]
      _exists = target.any? { |t| !t.nil? && !t.is_a?(NotFound) }
    else
      _exists = true unless target.is_a?(NotFound)
    end
  end
  _exists
end

#valueObject



53
54
55
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 53

def value
  get_member_value
end

#value=(new_value) ⇒ Object



57
58
59
# File 'lib/apimatic-core/utilities/json_pointer.rb', line 57

def value=(new_value)
  set_member_value(new_value)
end