class Hana::Patch
Public Class Methods
new(is)
click to toggle source
# File lib/hana.rb, line 88 def initialize is @is = is end
Public Instance Methods
apply(doc)
click to toggle source
# File lib/hana.rb, line 94 def apply doc @is.inject(doc) { |d, ins| send VALID.fetch(ins['op'].strip) { |k| raise Exception, "bad method `#{k}`" }, ins, d } end
Private Instance Methods
add(ins, doc)
click to toggle source
# File lib/hana.rb, line 107 def add ins, doc path = get_path ins list = Pointer.parse path key = list.pop dest = Pointer.eval list, doc obj = ins.fetch VALUE raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest if key add_op dest, key, obj else if doc.equal? dest doc = obj else dest.replace obj end end doc end
add_op(dest, key, obj)
click to toggle source
# File lib/hana.rb, line 223 def add_op dest, key, obj if Array === dest dest.insert check_index(dest, key), obj else raise Patch::InvalidObjectOperationException, "cannot add key '#{key}' to non-object" unless Hash === dest dest[key] = obj end end
check_index(obj, key)
click to toggle source
# File lib/hana.rb, line 214 def check_index obj, key return -1 if key == '-' raise ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless key =~ /\A-?\d+\Z/ idx = key.to_i raise OutOfBoundsException, "key '#{key}' is out of bounds for array" if idx > obj.length || idx < 0 idx end
copy(ins, doc)
click to toggle source
# File lib/hana.rb, line 144 def copy ins, doc path = get_path ins from = Pointer.parse ins.fetch FROM to = Pointer.parse path from_key = from.pop key = to.pop src = Pointer.eval from, doc dest = Pointer.eval to, doc if Array === src raise Patch::ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless from_key =~ /\A\d+\Z/ obj = src.fetch from_key.to_i else begin obj = src.fetch from_key rescue KeyError, NoMethodError raise Hana::Patch::MissingTargetException, "'from' location '#{ins.fetch FROM}' does not exist" end end raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest add_op dest, key, obj doc end
get_path(ins)
click to toggle source
# File lib/hana.rb, line 202 def get_path ins unless ins.key?('path') raise Hana::Patch::InvalidPath, "missing 'path' parameter" end unless ins['path'] raise Hana::Patch::InvalidPath, "null is not valid value for 'path'" end ins['path'] end
move(ins, doc)
click to toggle source
# File lib/hana.rb, line 128 def move ins, doc path = get_path ins from = Pointer.parse ins.fetch FROM to = Pointer.parse path from_key = from.pop key = to.pop src = Pointer.eval from, doc dest = Pointer.eval to, doc raise(MissingTargetException, "target location '#{ins['path']}' does not exist") unless dest obj = rm_op src, from_key add_op dest, key, obj doc end
remove(ins, doc)
click to toggle source
# File lib/hana.rb, line 193 def remove ins, doc path = get_path ins list = Pointer.parse path key = list.pop obj = Pointer.eval list, doc rm_op obj, key doc end
replace(ins, doc)
click to toggle source
# File lib/hana.rb, line 180 def replace ins, doc path = get_path ins list = Pointer.parse path key = list.pop obj = Pointer.eval list, doc return ins.fetch VALUE unless key rm_op obj, key add_op obj, key, ins.fetch(VALUE) doc end
rm_op(obj, key)
click to toggle source
# File lib/hana.rb, line 232 def rm_op obj, key if Array === obj raise Patch::ObjectOperationOnArrayException, "cannot apply non-numeric key '#{key}' to array" unless key =~ /\A\d+\Z/ key = key.to_i raise Patch::OutOfBoundsException, "key '#{key}' is out of bounds for array" if key >= obj.length obj.delete_at key else begin raise Patch::MissingTargetException, "key '#{key}' not found" unless obj&.key? key obj.delete key rescue ::NoMethodError raise Patch::InvalidObjectOperationException, "cannot remove key '#{key}' from non-object" end end end
test(ins, doc)
click to toggle source
# File lib/hana.rb, line 170 def test ins, doc path = get_path ins expected = Pointer.new(path).eval doc unless expected == ins.fetch(VALUE) raise FailedTestException.new(ins['path'], ins[VALUE]) end doc end