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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df28d5d017bd1ab98a68a0a52e4405fea97b552dba04f5994f0f5cdc047b13e6
4
- data.tar.gz: f2cae8902b0451e53e1a0e73ec6e4f675de0d8e95f432f64273d8e920faea5cc
3
+ metadata.gz: 1c4b549a75d02aacd916417297fcdfc3b3a208ed1327bb176522aaa396155f70
4
+ data.tar.gz: fc868171df7caee20cae4c04f60ecb2e7db1a85b23e2ac4a4dfc097085e15fa5
5
5
  SHA512:
6
- metadata.gz: 2d92cc98618b3fad9881fd45694b6f8e18b83467bf77904495f9398940a45fefebb93da0617ff2491afd9f53c53769499360dad9fb2d81db3bf88f9393fa0818
7
- data.tar.gz: 93694b232429c9dab07352cad06c498ccfc9aa899f51a61046a087c80a5835a4fa6ab8647931b81cc13dfe9ea82f51182ca2fbf5483903f2c5b724246b2e9dd0
6
+ metadata.gz: dcbf8a820eea98dc973874e500670a60d41366053103bf4ef6030500d7e9aa9fb6e4963b2730ea40122b8e96530ff5706b055ddd5fc42722b01f11c0f5b50c8f
7
+ data.tar.gz: '038d39b60d79d5f691f50ac326de84560181c16518bda086d12c4a32950156ad08a80db6097cb3e856caf24152e1e7b0c58f272a664905f01007f30a86132e8d'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shiny_json_logic (0.1.0)
4
+ shiny_json_logic (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -32,7 +32,7 @@ PLATFORMS
32
32
  ruby
33
33
 
34
34
  DEPENDENCIES
35
- bundler (~> 1.17)
35
+ bundler
36
36
  byebug
37
37
  pry
38
38
  rake (~> 10.0)
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,11 @@
1
+ require "shiny_json_logic/operations/base"
2
+
3
+ module ShinyJsonLogic
4
+ module Operations
5
+ class Coalesce < Base
6
+ def call
7
+ rules.compact.first
8
+ end
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,12 @@
1
+ require "shiny_json_logic/operations/base"
2
+
3
+ module ShinyJsonLogic
4
+ module Operations
5
+ class Val < Base
6
+ def call
7
+ data.dig(*rules)
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -1,3 +1,3 @@
1
1
  module ShinyJsonLogic
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -1,106 +1,8 @@
1
1
  require "shiny_json_logic/version"
2
- require "core_ext/array"
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
- if rule.is_a?(Hash)
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
@@ -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", "~> 1.17"
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.2
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: '1.17'
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: '1.17'
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