Class: Janeway::Interpreters::FilterSelectorInterpreter

Inherits:
Base
  • Object
show all
Defined in:
lib/janeway/interpreters/filter_selector_interpreter.rb

Overview

Interprets a filter selector, returns results or forwards them to next selector

Constant Summary

Constants inherited from Base

Base::NOTHING

Instance Attribute Summary

Attributes inherited from Base

#next, #node

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#to_s, #type

Constructor Details

#initialize(selector) ⇒ FilterSelectorInterpreter

Set up the internal interpreter chain for the FilterSelector.

Parameters:



13
14
15
16
# File 'lib/janeway/interpreters/filter_selector_interpreter.rb', line 13

def initialize(selector)
  super
  @expr = self.class.setup_interpreter_tree(selector)
end

Class Method Details

.setup_interpreter_tree(selector) ⇒ Interpreters::Base

FIXME: should this be combined with similar func in Interpreter? FIXME: move this to a separate module?

Set up a tree of interpreters which can process input for the filter expression. For a jsonpath query like ‘$.a[[email protected] == $.x]’, this sets up interpreters for ‘@.b == $.x’.

Returns:



24
25
26
# File 'lib/janeway/interpreters/filter_selector_interpreter.rb', line 24

def self.setup_interpreter_tree(selector)
  TreeConstructor.ast_node_to_interpreter(selector.value)
end

Instance Method Details

#as_jsonHash

Returns:

  • (Hash)


98
99
100
# File 'lib/janeway/interpreters/filter_selector_interpreter.rb', line 98

def as_json
  { type: type, value: node.to_s, next: @next&.as_json }.compact
end

#interpret(input, _parent, root, path) ⇒ Object

Interpret selector on the input.

Parameters:

  • input (Array, Hash)

    the results of processing so far

  • _parent (Array, Hash)

    parent of the input object

  • root (Array, Hash)

    the entire input

  • path (Array<String>)

    elements of normalized path to the current input



33
34
35
36
37
38
39
# File 'lib/janeway/interpreters/filter_selector_interpreter.rb', line 33

def interpret(input, _parent, root, path)
  case input
  when Array then interpret_array(input, root, path)
  when Hash then interpret_hash(input, root, path)
  else [] # early exit
  end
end

#interpret_array(input, root, path) ⇒ Object

Interpret selector on the input.

Parameters:

  • input (Array)

    the results of processing so far

  • root (Array, Hash)

    the entire input

  • path (Array<String>)

    elements of normalized path to the current input



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/janeway/interpreters/filter_selector_interpreter.rb', line 73

def interpret_array(input, root, path)
  # Apply filter expressions to the input data
  node_list = []
  input.each_with_index do |value, i|
    # Run filter and interpret result
    result = @expr.interpret(value, nil, root, [])
    case result
    when TrueClass then node_list << [i, value] # comparison test - pass
    when FalseClass then nil # comparison test - fail
    when Array then node_list << [i, value] unless result.empty? # existence test - node list
    else
      node_list << [i, value] # existence test. Null values here == success.
    end
  end
  return node_list.map(&:last) unless @next

  # Apply child selector to each node in the output node list
  results = []
  node_list.each do |i, value|
    results.concat @next.interpret(value, input, root, path + [i])
  end
  results
end

#interpret_hash(input, root, path) ⇒ Object

Interpret selector on the input.

Parameters:

  • input (Hash)

    the results of processing so far

  • root (Array, Hash)

    the entire input

  • path (Array<String>)

    elements of normalized path to the current input



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/janeway/interpreters/filter_selector_interpreter.rb', line 45

def interpret_hash(input, root, path)
  # Apply filter expressions to the input data
  node_list = []
  input.each do |key, value|
    # Run filter and interpret result
    result = @expr.interpret(value, nil, root, [])
    case result
    when TrueClass then node_list << [key, value] # comparison test - pass
    when FalseClass then nil # comparison test - fail
    when Array then node_list << [key, value] unless result.empty? # existence test - node list
    else
      node_list << [key, value] # existence test. Null values here == success.
    end
  end
  return node_list.map(&:last) unless @next

  # Apply child selector to each node in the output node list
  results = []
  node_list.each do |key, value|
    results.concat @next.interpret(value, input, root, path + [key])
  end
  results
end