shiny_json_logic 0.1.2 → 0.1.3
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 +4 -4
- data/Gemfile.lock +2 -2
- data/README.md +2 -2
- data/lib/shiny_json_logic/engine.rb +134 -0
- data/lib/shiny_json_logic/operations/coalesce.rb +11 -0
- data/lib/shiny_json_logic/operations/exists.rb +21 -0
- data/lib/shiny_json_logic/operations/val.rb +12 -0
- data/lib/shiny_json_logic/version.rb +1 -1
- data/lib/shiny_json_logic.rb +2 -100
- data/shiny_json_logic.gemspec +1 -1
- metadata +9 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c4b549a75d02aacd916417297fcdfc3b3a208ed1327bb176522aaa396155f70
|
|
4
|
+
data.tar.gz: fc868171df7caee20cae4c04f60ecb2e7db1a85b23e2ac4a4dfc097085e15fa5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dcbf8a820eea98dc973874e500670a60d41366053103bf4ef6030500d7e9aa9fb6e4963b2730ea40122b8e96530ff5706b055ddd5fc42722b01f11c0f5b50c8f
|
|
7
|
+
data.tar.gz: '038d39b60d79d5f691f50ac326de84560181c16518bda086d12c4a32950156ad08a80db6097cb3e856caf24152e1e7b0c58f272a664905f01007f30a86132e8d'
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -82,7 +82,7 @@ The goal is full JSON Logic coverage. Currently supported:
|
|
|
82
82
|
|
|
83
83
|
#### Data access
|
|
84
84
|
|
|
85
|
-
`var, missing, missing_some`
|
|
85
|
+
`var, missing, missing_some, val, exists`
|
|
86
86
|
|
|
87
87
|
#### Math
|
|
88
88
|
|
|
@@ -95,7 +95,7 @@ The goal is full JSON Logic coverage. Currently supported:
|
|
|
95
95
|
|
|
96
96
|
#### Arrays
|
|
97
97
|
|
|
98
|
-
`merge, in`
|
|
98
|
+
`merge, in, ?? (Coalesce operator)`
|
|
99
99
|
|
|
100
100
|
#### Iterable operations
|
|
101
101
|
`map, reduce, filter, some, all, none`
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require "core_ext/array"
|
|
2
|
+
require "core_ext/hash"
|
|
3
|
+
Dir[File.join(__dir__, "operations/**/*.rb")].each do |file|
|
|
4
|
+
require file
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module ShinyJsonLogic
|
|
8
|
+
class Engine
|
|
9
|
+
def initialize(rule, data = {})
|
|
10
|
+
@rule = rule
|
|
11
|
+
@data = data
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call(rule = self.rule, data = self.data)
|
|
15
|
+
stack = [[rule, data, :enter]]
|
|
16
|
+
results = []
|
|
17
|
+
|
|
18
|
+
while stack.any?
|
|
19
|
+
node, ctx, state = stack.pop
|
|
20
|
+
|
|
21
|
+
if state == :exit
|
|
22
|
+
# Already evaluated children, we solve
|
|
23
|
+
if node.is_a?(Hash)
|
|
24
|
+
op, raw_args = node.to_a.first
|
|
25
|
+
|
|
26
|
+
if collection_solvers.key?(op)
|
|
27
|
+
results << collection_solvers.fetch(op).new(raw_args, ctx).call
|
|
28
|
+
else
|
|
29
|
+
if raw_args.is_a?(Array)
|
|
30
|
+
argc = raw_args.size
|
|
31
|
+
args = results.pop(argc)
|
|
32
|
+
results << solvers.fetch(op).new(args, ctx).call
|
|
33
|
+
else
|
|
34
|
+
child = results.pop
|
|
35
|
+
|
|
36
|
+
args =
|
|
37
|
+
if child.nil?
|
|
38
|
+
[]
|
|
39
|
+
elsif child.is_a?(Array)
|
|
40
|
+
child
|
|
41
|
+
else
|
|
42
|
+
[child]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
results << solvers.fetch(op).new(args, ctx).call
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
elsif node.is_a?(Array)
|
|
50
|
+
results << results.pop(node.size)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
next
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# ENTER phase
|
|
57
|
+
case node
|
|
58
|
+
when Hash
|
|
59
|
+
op, raw_args = node.to_a.first
|
|
60
|
+
|
|
61
|
+
stack << [node, ctx, :exit]
|
|
62
|
+
|
|
63
|
+
unless collection_solvers.key?(op)
|
|
64
|
+
if raw_args.is_a?(Array)
|
|
65
|
+
raw_args.reverse_each { |a| stack << [a, ctx, :enter] }
|
|
66
|
+
else
|
|
67
|
+
stack << [raw_args, ctx, :enter]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
when Array
|
|
72
|
+
stack << [node, ctx, :exit]
|
|
73
|
+
node.reverse_each { |n| stack << [n, ctx, :enter] }
|
|
74
|
+
|
|
75
|
+
else
|
|
76
|
+
results << node
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
results.last
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
attr_reader :rule, :data
|
|
86
|
+
|
|
87
|
+
def solvers
|
|
88
|
+
@@solvers ||= {
|
|
89
|
+
"var" => ::ShinyJsonLogic::Operations::Var,
|
|
90
|
+
"missing" => ::ShinyJsonLogic::Operations::Missing,
|
|
91
|
+
"missing_some" => ::ShinyJsonLogic::Operations::MissingSome,
|
|
92
|
+
"if" => ::ShinyJsonLogic::Operations::If,
|
|
93
|
+
"==" => ::ShinyJsonLogic::Operations::Equal,
|
|
94
|
+
"===" => ::ShinyJsonLogic::Operations::StrictEqual,
|
|
95
|
+
"!=" => ::ShinyJsonLogic::Operations::Different,
|
|
96
|
+
"!==" => ::ShinyJsonLogic::Operations::StrictDifferent,
|
|
97
|
+
">" => ::ShinyJsonLogic::Operations::Greater,
|
|
98
|
+
">=" => ::ShinyJsonLogic::Operations::GreaterEqual,
|
|
99
|
+
"<" => ::ShinyJsonLogic::Operations::Smaller,
|
|
100
|
+
"<=" => ::ShinyJsonLogic::Operations::SmallerEqual,
|
|
101
|
+
"!" => ::ShinyJsonLogic::Operations::Not,
|
|
102
|
+
"or" => ::ShinyJsonLogic::Operations::Or,
|
|
103
|
+
"and" => ::ShinyJsonLogic::Operations::And,
|
|
104
|
+
"?:" => ::ShinyJsonLogic::Operations::If,
|
|
105
|
+
"in" => ::ShinyJsonLogic::Operations::Inclusion,
|
|
106
|
+
"cat" => ::ShinyJsonLogic::Operations::Concatenation,
|
|
107
|
+
"%" => ::ShinyJsonLogic::Operations::Modulo,
|
|
108
|
+
"max" => ::ShinyJsonLogic::Operations::Max,
|
|
109
|
+
"min" => ::ShinyJsonLogic::Operations::Min,
|
|
110
|
+
"+" => ::ShinyJsonLogic::Operations::Addition,
|
|
111
|
+
"*" => ::ShinyJsonLogic::Operations::Product,
|
|
112
|
+
"-" => ::ShinyJsonLogic::Operations::Subtraction,
|
|
113
|
+
"/" => ::ShinyJsonLogic::Operations::Division,
|
|
114
|
+
"substr" => ::ShinyJsonLogic::Operations::Substring,
|
|
115
|
+
"merge" => ::ShinyJsonLogic::Operations::Merge,
|
|
116
|
+
"!!" => ::ShinyJsonLogic::Operations::DoubleNot,
|
|
117
|
+
"val" => ::ShinyJsonLogic::Operations::Val,
|
|
118
|
+
"??" => ::ShinyJsonLogic::Operations::Coalesce,
|
|
119
|
+
"exists" => ::ShinyJsonLogic::Operations::Exists,
|
|
120
|
+
}
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def collection_solvers
|
|
124
|
+
@@collection_solvers ||= {
|
|
125
|
+
"filter" => ::ShinyJsonLogic::Operations::Filter,
|
|
126
|
+
"map" => ::ShinyJsonLogic::Operations::Map,
|
|
127
|
+
"reduce" => ::ShinyJsonLogic::Operations::Reduce,
|
|
128
|
+
"all" => ::ShinyJsonLogic::Operations::All,
|
|
129
|
+
"none" => ::ShinyJsonLogic::Operations::None,
|
|
130
|
+
"some" => ::ShinyJsonLogic::Operations::Some,
|
|
131
|
+
}
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "shiny_json_logic/operations/base"
|
|
2
|
+
|
|
3
|
+
module ShinyJsonLogic
|
|
4
|
+
module Operations
|
|
5
|
+
class Exists < Base
|
|
6
|
+
def call
|
|
7
|
+
current = data
|
|
8
|
+
|
|
9
|
+
Array.wrap(rules).each do |segment|
|
|
10
|
+
return false unless current.key?(segment)
|
|
11
|
+
|
|
12
|
+
current = current[segment]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
true
|
|
16
|
+
rescue
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/shiny_json_logic.rb
CHANGED
|
@@ -1,106 +1,8 @@
|
|
|
1
1
|
require "shiny_json_logic/version"
|
|
2
|
-
require "
|
|
3
|
-
require "core_ext/hash"
|
|
4
|
-
require "shiny_json_logic/operations/var"
|
|
5
|
-
require "shiny_json_logic/operations/missing"
|
|
6
|
-
require "shiny_json_logic/operations/missing_some"
|
|
7
|
-
require "shiny_json_logic/operations/if"
|
|
8
|
-
require "shiny_json_logic/operations/equal"
|
|
9
|
-
require "shiny_json_logic/operations/strict_equal"
|
|
10
|
-
require "shiny_json_logic/operations/different"
|
|
11
|
-
require "shiny_json_logic/operations/strict_different"
|
|
12
|
-
require "shiny_json_logic/operations/greater"
|
|
13
|
-
require "shiny_json_logic/operations/greater_equal"
|
|
14
|
-
require "shiny_json_logic/operations/smaller"
|
|
15
|
-
require "shiny_json_logic/operations/smaller_equal"
|
|
16
|
-
require "shiny_json_logic/operations/not"
|
|
17
|
-
require "shiny_json_logic/operations/or"
|
|
18
|
-
require "shiny_json_logic/operations/and"
|
|
19
|
-
require "shiny_json_logic/operations/inclusion"
|
|
20
|
-
require "shiny_json_logic/operations/concatenation"
|
|
21
|
-
require "shiny_json_logic/operations/modulo"
|
|
22
|
-
require "shiny_json_logic/operations/max"
|
|
23
|
-
require "shiny_json_logic/operations/min"
|
|
24
|
-
require "shiny_json_logic/operations/addition"
|
|
25
|
-
require "shiny_json_logic/operations/product"
|
|
26
|
-
require "shiny_json_logic/operations/subtraction"
|
|
27
|
-
require "shiny_json_logic/operations/division"
|
|
28
|
-
require "shiny_json_logic/operations/substring"
|
|
29
|
-
require "shiny_json_logic/operations/merge"
|
|
30
|
-
require "shiny_json_logic/operations/double_not"
|
|
31
|
-
require "shiny_json_logic/operations/filter"
|
|
32
|
-
require "shiny_json_logic/operations/map"
|
|
33
|
-
require "shiny_json_logic/operations/reduce"
|
|
34
|
-
require "shiny_json_logic/operations/all"
|
|
35
|
-
require "shiny_json_logic/operations/none"
|
|
36
|
-
require "shiny_json_logic/operations/some"
|
|
2
|
+
require "shiny_json_logic/engine"
|
|
37
3
|
|
|
38
4
|
module ShinyJsonLogic
|
|
39
|
-
class Error < StandardError; end
|
|
40
|
-
|
|
41
5
|
def self.apply(rule, data = {})
|
|
42
|
-
|
|
43
|
-
operation, raw_args = rule.to_a.first
|
|
44
|
-
if collection_solvers.key?(operation)
|
|
45
|
-
collection_solvers.fetch(operation).new(raw_args, data).call
|
|
46
|
-
else
|
|
47
|
-
evaluated_args =
|
|
48
|
-
if raw_args.is_a?(Array)
|
|
49
|
-
raw_args.map { |val| apply(val, data) }
|
|
50
|
-
else
|
|
51
|
-
Array.wrap(apply(raw_args, data))
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
solvers.fetch(operation).new(evaluated_args, data).call
|
|
55
|
-
end
|
|
56
|
-
elsif rule.is_a?(Array)
|
|
57
|
-
rule.map { |item| apply(item, data) }
|
|
58
|
-
else
|
|
59
|
-
rule
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def self.solvers
|
|
64
|
-
{
|
|
65
|
-
"var" => Operations::Var,
|
|
66
|
-
"missing" => Operations::Missing,
|
|
67
|
-
"missing_some" => Operations::MissingSome,
|
|
68
|
-
"if" => Operations::If,
|
|
69
|
-
"==" => Operations::Equal,
|
|
70
|
-
"===" => Operations::StrictEqual,
|
|
71
|
-
"!=" => Operations::Different,
|
|
72
|
-
"!==" => Operations::StrictDifferent,
|
|
73
|
-
">" => Operations::Greater,
|
|
74
|
-
">=" => Operations::GreaterEqual,
|
|
75
|
-
"<" => Operations::Smaller,
|
|
76
|
-
"<=" => Operations::SmallerEqual,
|
|
77
|
-
"!" => Operations::Not,
|
|
78
|
-
"or" => Operations::Or,
|
|
79
|
-
"and" => Operations::And,
|
|
80
|
-
"?:" => Operations::If,
|
|
81
|
-
"in" => Operations::Inclusion,
|
|
82
|
-
"cat" => Operations::Concatenation,
|
|
83
|
-
"%" => Operations::Modulo,
|
|
84
|
-
"max" => Operations::Max,
|
|
85
|
-
"min" => Operations::Min,
|
|
86
|
-
"+" => Operations::Addition,
|
|
87
|
-
"*" => Operations::Product,
|
|
88
|
-
"-" => Operations::Subtraction,
|
|
89
|
-
"/" => Operations::Division,
|
|
90
|
-
"substr" => Operations::Substring,
|
|
91
|
-
"merge" => Operations::Merge,
|
|
92
|
-
"!!" => Operations::DoubleNot,
|
|
93
|
-
}
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def self.collection_solvers
|
|
97
|
-
{
|
|
98
|
-
"filter" => Operations::Filter,
|
|
99
|
-
"map" => Operations::Map,
|
|
100
|
-
"reduce" => Operations::Reduce,
|
|
101
|
-
"all" => Operations::All,
|
|
102
|
-
"none" => Operations::None,
|
|
103
|
-
"some" => Operations::Some,
|
|
104
|
-
}
|
|
6
|
+
Engine.new(rule, data).call
|
|
105
7
|
end
|
|
106
8
|
end
|
data/shiny_json_logic.gemspec
CHANGED
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
|
25
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
26
26
|
spec.require_paths = ["lib"]
|
|
27
27
|
|
|
28
|
-
spec.add_development_dependency "bundler"
|
|
28
|
+
spec.add_development_dependency "bundler"
|
|
29
29
|
spec.add_development_dependency "rake", "~> 10.0"
|
|
30
30
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
31
31
|
spec.add_development_dependency 'byebug'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shiny_json_logic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Luis Moyano
|
|
@@ -13,16 +13,16 @@ dependencies:
|
|
|
13
13
|
name: bundler
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '
|
|
18
|
+
version: '0'
|
|
19
19
|
type: :development
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
|
-
- - "
|
|
23
|
+
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '
|
|
25
|
+
version: '0'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: rake
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,15 +107,18 @@ files:
|
|
|
107
107
|
- lib/core_ext/array.rb
|
|
108
108
|
- lib/core_ext/hash.rb
|
|
109
109
|
- lib/shiny_json_logic.rb
|
|
110
|
+
- lib/shiny_json_logic/engine.rb
|
|
110
111
|
- lib/shiny_json_logic/operations/addition.rb
|
|
111
112
|
- lib/shiny_json_logic/operations/all.rb
|
|
112
113
|
- lib/shiny_json_logic/operations/and.rb
|
|
113
114
|
- lib/shiny_json_logic/operations/base.rb
|
|
115
|
+
- lib/shiny_json_logic/operations/coalesce.rb
|
|
114
116
|
- lib/shiny_json_logic/operations/concatenation.rb
|
|
115
117
|
- lib/shiny_json_logic/operations/different.rb
|
|
116
118
|
- lib/shiny_json_logic/operations/division.rb
|
|
117
119
|
- lib/shiny_json_logic/operations/double_not.rb
|
|
118
120
|
- lib/shiny_json_logic/operations/equal.rb
|
|
121
|
+
- lib/shiny_json_logic/operations/exists.rb
|
|
119
122
|
- lib/shiny_json_logic/operations/filter.rb
|
|
120
123
|
- lib/shiny_json_logic/operations/greater.rb
|
|
121
124
|
- lib/shiny_json_logic/operations/greater_equal.rb
|
|
@@ -141,6 +144,7 @@ files:
|
|
|
141
144
|
- lib/shiny_json_logic/operations/strict_equal.rb
|
|
142
145
|
- lib/shiny_json_logic/operations/substring.rb
|
|
143
146
|
- lib/shiny_json_logic/operations/subtraction.rb
|
|
147
|
+
- lib/shiny_json_logic/operations/val.rb
|
|
144
148
|
- lib/shiny_json_logic/operations/var.rb
|
|
145
149
|
- lib/shiny_json_logic/truthy.rb
|
|
146
150
|
- lib/shiny_json_logic/version.rb
|