class JsonPointer::Evaluator
Evaluates a JSON pointer within a JSON document.
Note that this class is designed to evaluate references across a plain JSON data object or an instance of `JsonSchema::Schema`, so the constructor's `data` argument can be of either type.
Public Class Methods
new(data)
click to toggle source
# File lib/json_pointer/evaluator.rb, line 8 def initialize(data) @data = data end
Public Instance Methods
evaluate(original_path)
click to toggle source
# File lib/json_pointer/evaluator.rb, line 12 def evaluate(original_path) path = original_path # the leading # can either be included or not path = path[1..-1] if path[0] == "#" # special case on "" or presumably "#" if path.empty? return @data end if path[0] != "/" raise ArgumentError, %{Path must begin with a leading "/": #{original_path}.} end path_parts = split(path) evaluate_segment(@data, path_parts) end
Private Instance Methods
evaluate_segment(data, path_parts)
click to toggle source
# File lib/json_pointer/evaluator.rb, line 33 def evaluate_segment(data, path_parts) if path_parts.empty? data elsif data == nil # spec doesn't define how to handle this, so we'll return `nil` nil else key = transform_key(path_parts.shift) if data.is_a?(Array) unless key =~ /^\d+$/ raise ArgumentError, %{Key operating on an array must be a digit or "-": #{key}.} end evaluate_segment(data[key.to_i], path_parts) else evaluate_segment(data[key], path_parts) end end end
split(path)
click to toggle source
custom split method to account for blank segments
# File lib/json_pointer/evaluator.rb, line 53 def split(path) parts = [] last_index = 0 while index = path.index("/", last_index) if index == last_index parts << "" else parts << path[last_index...index] end last_index = index + 1 end # and also get that last segment parts << path[last_index..-1] # it should begin with a blank segment from the leading "/"; kill that parts.shift parts end
transform_key(key)
click to toggle source
# File lib/json_pointer/evaluator.rb, line 71 def transform_key(key) # ~ has special meaning to JSON pointer to allow keys containing "/", so # perform some transformations first as defined by the spec # first as defined by the spec key = key.gsub('~1', '/') key = key.gsub('~0', '~') key end