lib/jsonpathv2/enumerable.rb in jsonpathv2-0.0.4 vs lib/jsonpathv2/enumerable.rb in jsonpathv2-0.0.6
- old
+ new
@@ -24,63 +24,14 @@
when '*', '..', '@'
each(context, key, pos + 1, &blk)
when '$'
each(context, key, pos + 1, &blk) if node == @object
when /^\[(.*)\]$/
- expr[1, expr.size - 2].split(',').each do |sub_path|
- case sub_path[0]
- when '\'', '"'
- if node.is_a?(Hash)
- k = sub_path[1, sub_path.size - 2]
- each(node, k, pos + 1, &blk) if node.key?(k)
- end
- when '?'
- raise 'Cannot use ?(...) unless eval is enabled' unless allow_eval?
- case node
- when Array
- node.size.times do |index|
- @_current_node = node[index]
- if process_function_or_literal(sub_path[1, sub_path.size - 1])
- each(@_current_node, nil, pos + 1, &blk)
- end
- end
- when Hash
- if process_function_or_literal(sub_path[1, sub_path.size - 1])
- each(@_current_node, nil, pos + 1, &blk)
- end
- else
- yield node if process_function_or_literal(sub_path[1, sub_path.size - 1])
- end
- else
- if node.is_a?(Array)
- next if node.empty?
- array_args = sub_path.split(':')
- if array_args[0] == '*'
- start_idx = 0
- end_idx = node.size - 1
- else
- start_idx = process_function_or_literal(array_args[0], 0)
- next unless start_idx
- end_idx = (array_args[1] && process_function_or_literal(array_args[1], -1) || (sub_path.count(':') == 0 ? start_idx : -1))
- next unless end_idx
- if start_idx == end_idx
- next unless start_idx < node.size
- end
- end
- start_idx %= node.size
- end_idx %= node.size
- step = process_function_or_literal(array_args[2], 1)
- next unless step
- (start_idx..end_idx).step(step) { |i| each(node, i, pos + 1, &blk) }
- end
- end
- end
+ handle_wildecard(node, expr, context, key, pos, &blk)
else
if pos == (@path.size - 1) && node && allow_eval?
- if eval("node #{@path[pos]}")
- yield_value(blk, context, key)
- end
+ yield_value(blk, context, key) if eval("node #{@path[pos]}")
end
end
if pos > 0 && @path[pos - 1] == '..'
case node
@@ -89,9 +40,59 @@
end
end
end
private
+
+ def handle_wildecard(node, expr, context, key, pos, &blk)
+ expr[1, expr.size - 2].split(',').each do |sub_path|
+ case sub_path[0]
+ when '\'', '"'
+ next unless node.is_a?(Hash)
+ k = sub_path[1, sub_path.size - 2]
+ each(node, k, pos + 1, &blk) if node.key?(k)
+ when '?'
+ handle_question_mark(sub_path, node, pos, &blk)
+ else
+ next unless node.is_a?(Array) && !node.empty?
+ array_args = sub_path.split(':')
+ if array_args[0] == '*'
+ start_idx = 0
+ end_idx = node.size - 1
+ else
+ start_idx = process_function_or_literal(array_args[0], 0)
+ next unless start_idx
+ end_idx = (array_args[1] && process_function_or_literal(array_args[1], -1) || (sub_path.count(':') == 0 ? start_idx : -1))
+ next unless end_idx
+ next if start_idx == end_idx && start_idx > node.size
+ end
+ start_idx %= node.size
+ end_idx %= node.size
+ step = process_function_or_literal(array_args[2], 1)
+ next unless step
+ (start_idx..end_idx).step(step) { |i| each(node, i, pos + 1, &blk) }
+ end
+ end
+ end
+
+ def handle_question_mark(sub_path, node, pos, &blk)
+ raise 'Cannot use ?(...) unless eval is enabled' unless allow_eval?
+ case node
+ when Array
+ node.size.times do |index|
+ @_current_node = node[index]
+ if process_function_or_literal(sub_path[1, sub_path.size - 1])
+ each(@_current_node, nil, pos + 1, &blk)
+ end
+ end
+ when Hash
+ if process_function_or_literal(sub_path[1, sub_path.size - 1])
+ each(@_current_node, nil, pos + 1, &blk)
+ end
+ else
+ yield node if process_function_or_literal(sub_path[1, sub_path.size - 1])
+ end
+ end
def yield_value(blk, context, key)
case @mode
when nil
blk.call(key ? context[key] : context)