Class: Janeway::Interpreters::FunctionInterpreter

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

Overview

Interprets a jsonpath function call within a filter selector.

Constant Summary collapse

FUNCTION_PARAMETER_TYPES =

Specify the parameter types that built-in JsonPath functions require

Returns:

  • (Hash<Symbol, Array<Symbol>] function name => list of parameter types)

    Hash<Symbol, Array<Symbol>] function name => list of parameter types

{
  length: [:value_type],
  count: [:nodes_type],
  match: i[value_type value_type],
  search: i[value_type value_type],
  value: [:nodes_type],
}.freeze

Constants inherited from Base

Base::NOTHING

Instance Attribute Summary

Attributes inherited from Base

#next, #node

Instance Method Summary collapse

Constructor Details

#initialize(function) ⇒ FunctionInterpreter

Returns a new instance of FunctionInterpreter.

Parameters:



22
23
24
25
# File 'lib/janeway/interpreters/function_interpreter.rb', line 22

def initialize(function)
  super
  @params = function.parameters.map { |param| TreeConstructor.ast_node_to_interpreter(param) }
end

Instance Method Details

#deconstruct(input) ⇒ Object

Prepare a value to be passed to as a parameter with type ValueType. Singular queries (see RFC) produce a node list containing one value. Return the value.

Implements this part of the RFC:

> When the declared type of the parameter is ValueType and
  the argument is one of the following:
> ...
>
> A singular query. In this case:
> * If the query results in a nodelist consisting of a single node,
    the argument is the value of the node.
> * If the query results in an empty nodelist, the argument is
    the special result Nothing.

Parameters:

  • input (Object)

    usually an array - sometimes a basic type like String, Numeric

Returns:

  • (Object)

    basic type – string or number



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/janeway/interpreters/function_interpreter.rb', line 85

def deconstruct(input)
  return input unless input.is_a?(Array)

  if input.size == 1
    # FIXME: what if it was a size 1 array that was intended to be a node not a node list? How to detect this?
    input.first
  elsif input.empty?
    NOTHING
  else
    input # input is a single node, which happens to be an Array
  end
end

#interpret(input, root) ⇒ Object

Parameters:

  • input (Array, Hash)

    the results of processing so far

  • root (Array, Hash)

    the entire input



29
30
31
32
# File 'lib/janeway/interpreters/function_interpreter.rb', line 29

def interpret(input, root)
  params = interpret_function_parameters(@params, input, root)
  function.body.call(*params)
end

#interpret_function_parameters(parameters, input, root) ⇒ Array

Evaluate the expressions in the parameter list to make the parameter values to pass in to a JsonPath function.

The node lists returned by a singular query must be deconstructed into a single value for parameters of ValueType, this is done here. For explanation:

Parameters:

  • parameters (Array)

    parameters before evaluation

  • func (String)

    function name (eg. “length”, “count”)

  • input (Object)

Returns:

  • (Array)

    parameters after evaluation

See Also:



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

def interpret_function_parameters(parameters, input, root)
  param_types = FUNCTION_PARAMETER_TYPES[function.name.to_sym]

  parameters.map.with_index do |parameter, i|
    type = param_types[i]
    case parameter.node
    when AST::CurrentNode, AST::RootNode
      result = parameter.interpret(input, root)
      if type == :value_type && parameter.node.singular_query?
        deconstruct(result)
      else
        result
      end
    when AST::Function, AST::StringType then parameter.interpret(input, root)
    when String then parameter.value # from a TreeConstructor::Literal
    else
      # invalid parameter type. Function must accept it and return Nothing result
      parameter
    end
  end
end