json_logic 0.4.1 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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