Module: JSONLogic

Defined in:
lib/json_logic.rb,
lib/json_logic/version.rb,
lib/json_logic/operation.rb

Defined Under Namespace

Classes: Operation

Constant Summary collapse

VERSION =
'0.4.7'
ITERABLE_KEY =
"".freeze

Class Method Summary collapse

Class Method Details

.add_operation(operator, function) ⇒ Object



63
64
65
66
67
# File 'lib/json_logic.rb', line 63

def self.add_operation(operator, function)
  Operation.class.send(:define_method, operator) do |v, d|
    function.call(v, d)
  end
end

.apply(logic, data) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/json_logic.rb', line 6

def self.apply(logic, data)
  if logic.is_a?(Array)
    logic.map do |val|
      apply(val, data)
    end
  elsif !logic.is_a?(Hash)
    # Pass-thru
    logic
  else
    if data.is_a?(Hash)
      data = data.stringify_keys
    end
    data ||= {}

    operator, values = operator_and_values_from_logic(logic)
    Operation.perform(operator, values, data)
  end
end

.filter(logic, data) ⇒ Object



59
60
61
# File 'lib/json_logic.rb', line 59

def self.filter(logic, data)
  data.select { |d| apply(logic, d) }
end

.operator_and_values_from_logic(logic) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/json_logic.rb', line 47

def self.operator_and_values_from_logic(logic)
  # Unwrap single-key hash
  operator, values = logic.first

  # Ensure values is an array
  if !values.is_a?(Array)
    values = [values]
  end

  [operator, values]
end

.uses_data(logic) ⇒ Object

Return a list of the non-literal data used. Eg, if the logic contains a => ‘bananas’ operation, the result of uses_data on this logic will be a collection containing ‘bananas’



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/json_logic.rb', line 27

def self.uses_data(logic)
  collection = []

  if logic.kind_of?(Hash) || logic.kind_of?(Array) # If we are still dealing with logic, keep going. Else it's a value.
    operator, values = operator_and_values_from_logic(logic)

    if operator == 'var' # TODO: It may be that non-var operators use data so we may want a flag or collection that indicates data use.
      if values[0] != JSONLogic::ITERABLE_KEY
        collection << values[0]
      end
    else
      values.each do |val|
        collection.concat(uses_data(val))
      end
    end
  end

  return collection.uniq
end