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 +5 -5
- data/.travis.yml +2 -2
- data/LICENSE.txt +1 -1
- data/json_logic.gemspec +7 -4
- data/lib/core_ext/deep_fetch.rb +6 -2
- data/lib/json_logic.rb +46 -6
- data/lib/json_logic/operation.rb +30 -12
- data/lib/json_logic/truthy.rb +6 -0
- data/lib/json_logic/version.rb +1 -1
- metadata +40 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c8af2db5872f3fe1ff4ebf64aa0ca0b617f3238b6536c750a85f80e000e84881
|
4
|
+
data.tar.gz: b80fa16f7e15ee2025cdba337af89bafe6c777882763a8dfecc4427997ebc90c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc13699694479c8c33c582278bbf9e81d78292fa2665d477590c2bcf95f959711f635120174e040375009a0c55ac3ca3dd7ec627fc9ac17292ea93c037f7aea9
|
7
|
+
data.tar.gz: af2eec900330d7f48392ee7498dfce496a7a297ae4bf8dd75c64e78136d9f7b9ecee097d52e43d573bdad3e07be8b081d9fb6a961522b7a78e68b37631033988
|
data/.travis.yml
CHANGED
data/LICENSE.txt
CHANGED
@@ -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
|
data/json_logic.gemspec
CHANGED
@@ -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.
|
21
|
+
spec.required_ruby_version = '>= 2.2'
|
22
22
|
|
23
|
-
spec.add_development_dependency 'bundler', '
|
24
|
-
spec.add_development_dependency 'rake', '
|
25
|
-
spec.add_development_dependency 'minitest', '
|
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
|
data/lib/core_ext/deep_fetch.rb
CHANGED
@@ -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)
|
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)
|
14
|
+
value = dig(*indexes) rescue default
|
15
|
+
value.nil? ? default : value # value can be false (Boolean)
|
12
16
|
end
|
13
17
|
end
|
data/lib/json_logic.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
-
|
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)
|
data/lib/json_logic/operation.rb
CHANGED
@@ -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
|
-
|
6
|
-
|
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(&:
|
83
|
-
'>=' => ->(v, d) { v.map(&:
|
84
|
-
'<' => ->(v, d) { v.map(&:
|
85
|
-
'<=' => ->(v, d) { v.map(&:
|
86
|
-
'max' => ->(v, d) { v.map(&:
|
87
|
-
'min' => ->(v, d) { v.map(&:
|
88
|
-
'+' => ->(v, d) { v.map(&:
|
89
|
-
'-' => ->(v, d) { v.map!(&:
|
90
|
-
'*' => ->(v, d) { v.map(&:
|
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
|
}
|
data/lib/json_logic/truthy.rb
CHANGED
data/lib/json_logic/version.rb
CHANGED
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.
|
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:
|
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:
|
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:
|
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.
|
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
|
-
|
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
|