json_logic 0.4.1 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 677b105ac790d969a647b1244272dec1d489ce8f
4
- data.tar.gz: 2c2541c2edc2616d65e408084cb069350551dfa4
2
+ SHA256:
3
+ metadata.gz: c8af2db5872f3fe1ff4ebf64aa0ca0b617f3238b6536c750a85f80e000e84881
4
+ data.tar.gz: b80fa16f7e15ee2025cdba337af89bafe6c777882763a8dfecc4427997ebc90c
5
5
  SHA512:
6
- metadata.gz: 061f7d199adc1ddd4482aa446e10ea3cfadaeca343e4f4ec1de6629eab3db944828065ef4d123ac5153dcf16d8860a5767ec4f30767c411c4a0055233f5d4a45
7
- data.tar.gz: 8451f7ac97031790f913c6b223d243ec476ddf71e1205f19b1f604c6a182960aa860bbffee0117aa98e1d245e6ffd38ad0bf74ed5d69ff139d4c8f213ec7a3b0
6
+ metadata.gz: dc13699694479c8c33c582278bbf9e81d78292fa2665d477590c2bcf95f959711f635120174e040375009a0c55ac3ca3dd7ec627fc9ac17292ea93c037f7aea9
7
+ data.tar.gz: af2eec900330d7f48392ee7498dfce496a7a297ae4bf8dd75c64e78136d9f7b9ecee097d52e43d573bdad3e07be8b081d9fb6a961522b7a78e68b37631033988
@@ -1,5 +1,5 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.13.3
4
+ - 2.5.0
5
+ before_install: gem install bundler -v 2.0.1
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 Kenneth Geerts
3
+ Copyright (c) 2016 Kenneth Geerts, Jordan Prince
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,9 +18,12 @@ Gem::Specification.new do |spec|
18
18
  end
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.required_ruby_version = '>= 2.3'
21
+ spec.required_ruby_version = '>= 2.2'
22
22
 
23
- spec.add_development_dependency 'bundler', '~> 1.13'
24
- spec.add_development_dependency 'rake', '~> 10.0'
25
- spec.add_development_dependency 'minitest', '~> 5.0'
23
+ spec.add_development_dependency 'bundler', '>= 2.0.1'
24
+ spec.add_development_dependency 'rake', '>= 10.0'
25
+ spec.add_development_dependency 'minitest', '>= 5.0'
26
+ spec.add_development_dependency 'byebug'
27
+ spec.add_development_dependency 'pry'
28
+ spec.add_runtime_dependency 'backport_dig' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
26
29
  end
@@ -1,13 +1,17 @@
1
+ require 'backport_dig' if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
2
+
1
3
  class Hash
2
4
  def deep_fetch(key, default = nil)
3
5
  keys = key.to_s.split('.')
4
- dig(*keys) || default rescue default
6
+ value = dig(*keys) rescue default
7
+ value.nil? ? default : value # value can be false (Boolean)
5
8
  end
6
9
  end
7
10
 
8
11
  class Array
9
12
  def deep_fetch(index, default = nil)
10
13
  indexes = index.to_s.split('.').map(&:to_i)
11
- dig(*indexes) || default rescue default
14
+ value = dig(*indexes) rescue default
15
+ value.nil? ? default : value # value can be false (Boolean)
12
16
  end
13
17
  end
@@ -5,15 +5,55 @@ require 'json_logic/operation'
5
5
  module JSONLogic
6
6
  def self.apply(logic, data)
7
7
  if logic.is_a?(Array)
8
- return logic.map { |val| apply(val, data) }
8
+ logic.map do |val|
9
+ apply(val, data)
10
+ end
11
+ elsif !logic.is_a?(Hash)
12
+ # Pass-thru
13
+ logic
14
+ else
15
+ if data.is_a?(Hash)
16
+ data = data.stringify_keys
17
+ end
18
+ data ||= {}
19
+
20
+ operator, values = operator_and_values_from_logic(logic)
21
+ Operation.perform(operator, values, data)
22
+ end
23
+ end
24
+
25
+ # Return a list of the non-literal data used. Eg, if the logic contains a {'var' => 'bananas'} operation, the result of
26
+ # uses_data on this logic will be a collection containing 'bananas'
27
+ def self.uses_data(logic)
28
+ collection = []
29
+
30
+ if logic.kind_of?(Hash) || logic.kind_of?(Array) # If we are still dealing with logic, keep going. Else it's a value.
31
+ operator, values = operator_and_values_from_logic(logic)
32
+
33
+ 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.
34
+ if values[0] != JSONLogic::ITERABLE_KEY
35
+ collection << values[0]
36
+ end
37
+ else
38
+ values.each do |val|
39
+ collection.concat(uses_data(val))
40
+ end
41
+ end
9
42
  end
10
43
 
11
- return logic unless logic.is_a?(Hash) # pass-thru
44
+ return collection.uniq
45
+ end
46
+
47
+ def self.operator_and_values_from_logic(logic)
48
+ # Unwrap single-key hash
49
+ operator, values = logic.first
50
+
51
+ # Ensure values is an array
52
+ if !values.is_a?(Array)
53
+ values = [values]
54
+ end
12
55
 
13
- data = data.stringify_keys if data.is_a?(Hash) # Stringify keys to keep out problems with symbol/string mismatch
14
- operator, values = logic.first # unwrap single-key hash
15
- values = [values] unless values.is_a?(Array) # syntactic sugar
16
- Operation.perform(operator, values, data || {})
56
+ [operator, values]
17
57
  end
18
58
 
19
59
  def self.filter(logic, data)
@@ -1,9 +1,22 @@
1
1
  module JSONLogic
2
+ ITERABLE_KEY = "".freeze
3
+
2
4
  class Operation
3
5
  LAMBDAS = {
4
6
  'var' => ->(v, d) do
5
- return d unless d.is_a?(Hash) or d.is_a?(Array)
6
- return v == [""] ? (d.is_a?(Array) ? d : d[""]) : d.deep_fetch(*v)
7
+ if !(d.is_a?(Hash) || d.is_a?(Array))
8
+ d
9
+ else
10
+ if v == [JSONLogic::ITERABLE_KEY]
11
+ if d.is_a?(Array)
12
+ d
13
+ else
14
+ d[JSONLogic::ITERABLE_KEY]
15
+ end
16
+ else
17
+ d.deep_fetch(*v)
18
+ end
19
+ end
7
20
  end,
8
21
  'missing' => ->(v, d) { v.select { |val| d.deep_fetch(val).nil? } },
9
22
  'missing_some' => ->(v, d) {
@@ -11,11 +24,15 @@ module JSONLogic
11
24
  present.size >= v[0] ? [] : LAMBDAS['missing'].call(v[1], d)
12
25
  },
13
26
  'some' => -> (v,d) do
27
+ return false unless v[0].is_a?(Array)
28
+
14
29
  v[0].any? do |val|
15
30
  interpolated_block(v[1], val).truthy?
16
31
  end
17
32
  end,
18
33
  'filter' => -> (v,d) do
34
+ return [] unless v[0].is_a?(Array)
35
+
19
36
  v[0].select do |val|
20
37
  interpolated_block(v[1], val).truthy?
21
38
  end
@@ -79,19 +96,20 @@ module JSONLogic
79
96
  result.nil? ? v.last : result
80
97
  },
81
98
  '?:' => ->(v, d) { LAMBDAS['if'].call(v, d) },
82
- '>' => ->(v, d) { v.map(&:to_i).each_cons(2).all? { |i, j| i > j } },
83
- '>=' => ->(v, d) { v.map(&:to_i).each_cons(2).all? { |i, j| i >= j } },
84
- '<' => ->(v, d) { v.map(&:to_i).each_cons(2).all? { |i, j| i < j } },
85
- '<=' => ->(v, d) { v.map(&:to_i).each_cons(2).all? { |i, j| i <= j } },
86
- 'max' => ->(v, d) { v.map(&:to_i).max },
87
- 'min' => ->(v, d) { v.map(&:to_i).min },
88
- '+' => ->(v, d) { v.map(&:to_i).reduce(:+) },
89
- '-' => ->(v, d) { v.map!(&:to_i); v.size == 1 ? -v.first : v.reduce(:-) },
90
- '*' => ->(v, d) { v.map(&:to_i).reduce(:*) },
99
+ '>' => ->(v, d) { v.map(&:to_f).each_cons(2).all? { |i, j| i > j } },
100
+ '>=' => ->(v, d) { v.map(&:to_f).each_cons(2).all? { |i, j| i >= j } },
101
+ '<' => ->(v, d) { v.map(&:to_f).each_cons(2).all? { |i, j| i < j } },
102
+ '<=' => ->(v, d) { v.map(&:to_f).each_cons(2).all? { |i, j| i <= j } },
103
+ 'max' => ->(v, d) { v.map(&:to_f).max },
104
+ 'min' => ->(v, d) { v.map(&:to_f).min },
105
+ '+' => ->(v, d) { v.map(&:to_f).reduce(:+) },
106
+ '-' => ->(v, d) { v.map!(&:to_f); v.size == 1 ? -v.first : v.reduce(:-) },
107
+ '*' => ->(v, d) { v.map(&:to_f).reduce(:*) },
91
108
  '/' => ->(v, d) { v.map(&:to_f).reduce(:/) },
92
109
  '%' => ->(v, d) { v.map(&:to_i).reduce(:%) },
110
+ '^' => ->(v, d) { v.map(&:to_f).reduce(:**) },
93
111
  'merge' => ->(v, d) { v.flatten },
94
- 'in' => ->(v, d) { v[1].include? v[0] },
112
+ 'in' => ->(v, d) { interpolated_block(v[1], d).include? v[0] },
95
113
  'cat' => ->(v, d) { v.map(&:to_s).join },
96
114
  'log' => ->(v, d) { puts v }
97
115
  }
@@ -35,6 +35,12 @@ class Integer
35
35
  end
36
36
  end
37
37
 
38
+ class Float
39
+ def falsy?
40
+ zero?
41
+ end
42
+ end
43
+
38
44
  class Array
39
45
  def falsy?
40
46
  empty?
@@ -1,3 +1,3 @@
1
1
  module JSONLogic
2
- VERSION = '0.4.1'
2
+ VERSION = '0.4.7'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_logic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenneth Geerts
@@ -9,50 +9,78 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-10-31 00:00:00.000000000 Z
12
+ date: 2020-10-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '1.13'
20
+ version: 2.0.1
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - "~>"
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '1.13'
27
+ version: 2.0.1
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: '10.0'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '10.0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: minitest
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - "~>"
46
+ - - ">="
47
47
  - !ruby/object:Gem::Version
48
48
  version: '5.0'
49
49
  type: :development
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - "~>"
53
+ - - ">="
54
54
  - !ruby/object:Gem::Version
55
55
  version: '5.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: byebug
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: pry
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
56
84
  description: Build complex rules, serialize them as JSON, and execute them in ruby.
57
85
  See http://jsonlogic.com
58
86
  email:
@@ -90,15 +118,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
118
  requirements:
91
119
  - - ">="
92
120
  - !ruby/object:Gem::Version
93
- version: '2.3'
121
+ version: '2.2'
94
122
  required_rubygems_version: !ruby/object:Gem::Requirement
95
123
  requirements:
96
124
  - - ">="
97
125
  - !ruby/object:Gem::Version
98
126
  version: '0'
99
127
  requirements: []
100
- rubyforge_project:
101
- rubygems_version: 2.6.14
128
+ rubygems_version: 3.0.1
102
129
  signing_key:
103
130
  specification_version: 4
104
131
  summary: Build complex rules, serialize them as JSON, and execute them in ruby