Skip to content

Commit

Permalink
Merge pull request #22 from firehydrant/master
Browse files Browse the repository at this point in the history
Small Refactors
  • Loading branch information
bhgames authored Oct 6, 2020
2 parents 9343db0 + 5640e46 commit f185e59
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 21 deletions.
6 changes: 3 additions & 3 deletions json_logic.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ Gem::Specification.new do |spec|

spec.required_ruby_version = '>= 2.2'

spec.add_development_dependency 'bundler', '~> 2.0.1'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'minitest', '~> 5.0'
spec.add_development_dependency 'bundler', '>= 2.0.1'
spec.add_development_dependency 'rake', '>= 10.0'
spec.add_development_dependency 'minitest', '>= 5.0'
spec.add_development_dependency 'byebug'
spec.add_development_dependency 'pry'
spec.add_runtime_dependency 'backport_dig' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
Expand Down
56 changes: 40 additions & 16 deletions lib/json_logic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,57 @@
module JSONLogic
def self.apply(logic, data)
if logic.is_a?(Array)
return logic.map { |val| apply(val, data) }
end

return logic unless logic.is_a?(Hash) # pass-thru
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 ||= {}

data = data.stringify_keys if data.is_a?(Hash) # Stringify keys to keep out problems with symbol/string mismatch
operator, values = logic.first # unwrap single-key hash
values = [values] unless values.is_a?(Array) # syntactic sugar
Operation.perform(operator, values, data || {})
operator, values = operator_and_values_from_logic(logic)
Operation.perform(operator, values, data)
end
end

# Return a list of the non-literal data used. Eg, if the logic contains a {'var' => 'bananas'} operation, the result of
# uses_data on this logic will be a collection containing 'bananas'
def self.uses_data(logic)
collection = []

operator, values = logic.first
values = [values] unless values.is_a?(Array)
if operator == 'var'
collection << values[0]
else
values.each { |val|
collection.concat(uses_data(val))
}
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

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

def self.filter(logic, data)
data.select { |d| apply(logic, d) }
end
Expand Down
17 changes: 15 additions & 2 deletions lib/json_logic/operation.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
module JSONLogic
ITERABLE_KEY = "".freeze

class Operation
LAMBDAS = {
'var' => ->(v, d) do
return d unless d.is_a?(Hash) or d.is_a?(Array)
return v == [""] ? (d.is_a?(Array) ? d : d[""]) : d.deep_fetch(*v)
if !(d.is_a?(Hash) || d.is_a?(Array))
d
else
if v == [JSONLogic::ITERABLE_KEY]
if d.is_a?(Array)
d
else
d[JSONLogic::ITERABLE_KEY]
end
else
d.deep_fetch(*v)
end
end
end,
'missing' => ->(v, d) { v.select { |val| d.deep_fetch(val).nil? } },
'missing_some' => ->(v, d) {
Expand Down

0 comments on commit f185e59

Please sign in to comment.