Class: TentD::JsonPatch::HashPointer

Inherits:
Object
  • Object
show all
Defined in:
lib/tentd/json_patch.rb

Defined Under Namespace

Classes: Error, InvalidPointer

Instance Method Summary collapse

Constructor Details

#initialize(hash, pointer) ⇒ HashPointer

Returns a new instance of HashPointer.



12
13
14
# File 'lib/tentd/json_patch.rb', line 12

def initialize(hash, pointer)
  @hash, @pointer = hash, pointer
end

Instance Method Details

#deleteObject



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/tentd/json_patch.rb', line 45

def delete
  obj = keys[0..-2].inject(@hash) do |obj, key|
    obj[key]
  end
  if obj.kind_of?(Array)
    raise InvalidPointer if keys.last.to_i >= obj.size
    obj.delete_at(keys.last.to_i)
  else
    raise InvalidPointer unless obj.has_key?(keys.last)
    obj.delete(keys.last)
  end
end

#exists?Boolean

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/tentd/json_patch.rb', line 68

def exists?
  i = 0
  keys.inject(@hash) do |obj, key|
    # points to a key that doesn't exist
    break unless obj

    if obj.kind_of?(Array)
      return key.to_i < obj.size
    end

    return true if obj.kind_of?(Hash) && i == keys.size-1 && obj.has_key?(key)

    return false if obj[key].nil?

    return true if ![Hash, Array].include?(obj[key].class)

    i += 1
    obj[key]
  end
  false
end

#keysObject



103
104
105
106
107
# File 'lib/tentd/json_patch.rb', line 103

def keys
  @pointer.sub(%r{^/}, '').split("/").map do |key|
    unescape_key(key)
  end
end

#move_to(pointer) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/tentd/json_patch.rb', line 58

def move_to(pointer)
  _value = value
  to_pointer = self.class.new(@hash, pointer)
  if value_class == Array && to_pointer.value_class == Array && to_pointer.keys.last !~ /^\d+$/
    raise InvalidPointer
  end
  delete
  to_pointer.value = _value
end

#unescape_key(key) ⇒ Object



109
110
111
# File 'lib/tentd/json_patch.rb', line 109

def unescape_key(key)
  key.gsub(/~1/, '/').gsub(/~0/, '~')
end

#valueObject



16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/tentd/json_patch.rb', line 16

def value
  keys.inject(@hash) do |obj, key|
    if obj.kind_of?(Array)
      raise InvalidPointer if key.to_i >= obj.size
      obj[key.to_i]
    elsif obj.kind_of?(Hash)
      raise InvalidPointer unless obj.has_key?(key)
      obj[key]
    else
      raise InvalidPointer
    end
  end
end

#value=(value) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/tentd/json_patch.rb', line 30

def value=(value)
  if exists? && value_class == Array && keys.last !~ /^\d+$/
    raise InvalidPointer
  end
  obj = keys[0..-2].inject(@hash) do |obj, key|
    obj[key] = {} unless [Hash, Array].include?(obj[key].class)
    obj[key]
  end
  if obj.kind_of?(Array)
    obj.insert(keys.last.to_i, value)
  else
    obj[keys.last] = value
  end
end

#value_classObject



90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/tentd/json_patch.rb', line 90

def value_class
  i = 0
  keys.inject(@hash) do |obj, key|
    return unless obj

    return Array if obj.kind_of?(Array)
    return Hash if i == keys.size-1 && obj[key].kind_of?(Hash)

    i += 1
    obj[key]
  end
end