Class: Kumi::Core::Compiler::Accessors::EachIndexedAccessor
- Inherits:
-
Object
- Object
- Kumi::Core::Compiler::Accessors::EachIndexedAccessor
- Extended by:
- Base
- Defined in:
- lib/kumi/core/compiler/accessors/each_indexed_accessor.rb
Constant Summary
Constants included from Base
Class Method Summary collapse
- .build(operations, path_key, policy, key_policy, with_indices = true) ⇒ Object
-
.build_each_walker(operations, path_key, policy, key_policy) ⇒ Object
Depth-first traversal yielding (value, nd_index).
Methods included from Base
assert_array!, assert_hash!, fetch_key, missing_array_action, missing_key_action, next_enters_array?, warn_mismatch
Class Method Details
.build(operations, path_key, policy, key_policy, with_indices = true) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/kumi/core/compiler/accessors/each_indexed_accessor.rb', line 10 def self.build(operations, path_key, policy, key_policy, with_indices = true) walker = build_each_walker(operations, path_key, policy, key_policy) if with_indices lambda do |data, &blk| if blk walker.call(data, 0, [], ->(val, idx) { blk.call(val, idx) }) nil else out = [] walker.call(data, 0, [], ->(val, idx) { out << [val, idx] }) out end end else lambda do |data, &blk| if blk walker.call(data, 0, [], ->(val, _idx) { blk.call(val) }) nil else out = [] walker.call(data, 0, [], ->(val, _idx) { out << val }) out end end end end |
.build_each_walker(operations, path_key, policy, key_policy) ⇒ Object
Depth-first traversal yielding (value, nd_index)
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/kumi/core/compiler/accessors/each_indexed_accessor.rb', line 38 def self.build_each_walker(operations, path_key, policy, key_policy) mode = :each_indexed walk = nil walk = lambda do |node, pc, ndx, y| if pc >= operations.length y.call(node, ndx) return end op = operations[pc] case op[:type] when :enter_hash # If the *next* op is an array hop, relax to indifferent for that fetch policy_for = next_enters_array?(operations, pc) ? :indifferent : key_policy next_node = fetch_key(node, op[:key], policy_for) if next_node == Base::MISSING case missing_key_action(policy) when :yield_nil then y.call(nil, ndx) when :skip then return when :raise then raise KeyError, "Missing key '#{op[:key]}' at '#{path_key}' (#{mode})" end return end walk.call(next_node, pc + 1, ndx, y) when :enter_array if node.nil? case missing_array_action(policy) when :yield_nil then y.call(nil, ndx) when :skip then return when :raise then raise KeyError, "Missing array at '#{path_key}' (#{mode})" end return end assert_array!(node, path_key, mode) node.each_with_index { |child, i| walk.call(child, pc + 1, ndx + [i], y) } else raise "Unknown operation: #{op.inspect}" end end end |