shiny_json_logic 0.2.6 → 0.2.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 +4 -4
- data/AGENTS.md +131 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +39 -3
- data/badges/compat.json +2 -2
- data/lib/core_ext/array.rb +5 -0
- data/lib/shiny_json_logic/engine.rb +1 -13
- data/lib/shiny_json_logic/numericals/numerify.rb +9 -9
- data/lib/shiny_json_logic/numericals/with_error_handling.rb +15 -10
- data/lib/shiny_json_logic/operations/addition.rb +15 -5
- data/lib/shiny_json_logic/operations/all.rb +1 -1
- data/lib/shiny_json_logic/operations/and.rb +6 -1
- data/lib/shiny_json_logic/operations/base.rb +27 -0
- data/lib/shiny_json_logic/operations/coalesce.rb +5 -1
- data/lib/shiny_json_logic/operations/concatenation.rb +6 -3
- data/lib/shiny_json_logic/operations/different.rb +48 -4
- data/lib/shiny_json_logic/operations/division.rb +24 -11
- data/lib/shiny_json_logic/operations/double_not.rb +1 -1
- data/lib/shiny_json_logic/operations/equal.rb +44 -1
- data/lib/shiny_json_logic/operations/exists.rb +2 -2
- data/lib/shiny_json_logic/operations/filter.rb +2 -0
- data/lib/shiny_json_logic/operations/greater.rb +45 -1
- data/lib/shiny_json_logic/operations/greater_equal.rb +45 -1
- data/lib/shiny_json_logic/operations/inclusion.rb +3 -1
- data/lib/shiny_json_logic/operations/iterable/base.rb +25 -16
- data/lib/shiny_json_logic/operations/map.rb +10 -0
- data/lib/shiny_json_logic/operations/max.rb +7 -1
- data/lib/shiny_json_logic/operations/merge.rb +3 -1
- data/lib/shiny_json_logic/operations/min.rb +7 -1
- data/lib/shiny_json_logic/operations/missing.rb +8 -2
- data/lib/shiny_json_logic/operations/missing_some.rb +6 -4
- data/lib/shiny_json_logic/operations/modulo.rb +22 -3
- data/lib/shiny_json_logic/operations/none.rb +1 -1
- data/lib/shiny_json_logic/operations/not.rb +2 -1
- data/lib/shiny_json_logic/operations/or.rb +6 -1
- data/lib/shiny_json_logic/operations/product.rb +29 -2
- data/lib/shiny_json_logic/operations/smaller.rb +45 -1
- data/lib/shiny_json_logic/operations/smaller_equal.rb +45 -1
- data/lib/shiny_json_logic/operations/strict_different.rb +22 -4
- data/lib/shiny_json_logic/operations/strict_equal.rb +15 -3
- data/lib/shiny_json_logic/operations/substring.rb +3 -2
- data/lib/shiny_json_logic/operations/subtraction.rb +21 -3
- data/lib/shiny_json_logic/operations/throw.rb +1 -1
- data/lib/shiny_json_logic/operations/val.rb +4 -2
- data/lib/shiny_json_logic/operations/var.rb +3 -2
- data/lib/shiny_json_logic/operator_solver.rb +1 -1
- data/lib/shiny_json_logic/version.rb +1 -1
- data/lib/shiny_json_logic.rb +3 -0
- data/results/ruby.json +1 -1
- data/shiny_json_logic.gemspec +5 -5
- metadata +7 -5
|
@@ -1,12 +1,56 @@
|
|
|
1
1
|
require "shiny_json_logic/operations/base"
|
|
2
|
+
require "shiny_json_logic/numericals/with_error_handling"
|
|
3
|
+
require "shiny_json_logic/numericals/numerify"
|
|
2
4
|
|
|
3
5
|
module ShinyJsonLogic
|
|
4
6
|
module Operations
|
|
5
7
|
class Greater < Base
|
|
8
|
+
include Numericals::WithErrorHandling
|
|
9
|
+
include Numericals::Numerify
|
|
10
|
+
|
|
6
11
|
protected
|
|
7
12
|
|
|
8
13
|
def run
|
|
9
|
-
|
|
14
|
+
operands = Array.wrap_nil(rules)
|
|
15
|
+
return handle_invalid_args if operands.length < 2
|
|
16
|
+
|
|
17
|
+
prev = evaluate(operands[0])
|
|
18
|
+
operands[1..].each do |rule|
|
|
19
|
+
curr = evaluate(rule)
|
|
20
|
+
result = compare(prev, curr)
|
|
21
|
+
return handle_nan if result == :nan
|
|
22
|
+
return false unless result == 1
|
|
23
|
+
prev = curr
|
|
24
|
+
end
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def compare(a, b)
|
|
31
|
+
# Arrays u objetos → NaN
|
|
32
|
+
return :nan if a.is_a?(Array) || a.is_a?(Hash) || b.is_a?(Array) || b.is_a?(Hash)
|
|
33
|
+
|
|
34
|
+
# Ambos strings → comparación lexicográfica
|
|
35
|
+
if a.is_a?(String) && b.is_a?(String)
|
|
36
|
+
return a <=> b
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Convertir a números para comparar
|
|
40
|
+
num_a = numerify_for_compare(a)
|
|
41
|
+
num_b = numerify_for_compare(b)
|
|
42
|
+
return :nan if num_a.nil? || num_b.nil?
|
|
43
|
+
|
|
44
|
+
num_a <=> num_b
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def numerify_for_compare(value)
|
|
48
|
+
return value.to_f if value.is_a?(Numeric)
|
|
49
|
+
return 0.0 if value == false
|
|
50
|
+
return 1.0 if value == true
|
|
51
|
+
return 0.0 if value.nil?
|
|
52
|
+
return value.to_f if value.is_a?(String) && numeric_string?(value)
|
|
53
|
+
nil # String no numérica
|
|
10
54
|
end
|
|
11
55
|
end
|
|
12
56
|
end
|
|
@@ -1,12 +1,56 @@
|
|
|
1
1
|
require "shiny_json_logic/operations/base"
|
|
2
|
+
require "shiny_json_logic/numericals/with_error_handling"
|
|
3
|
+
require "shiny_json_logic/numericals/numerify"
|
|
2
4
|
|
|
3
5
|
module ShinyJsonLogic
|
|
4
6
|
module Operations
|
|
5
7
|
class GreaterEqual < Base
|
|
8
|
+
include Numericals::WithErrorHandling
|
|
9
|
+
include Numericals::Numerify
|
|
10
|
+
|
|
6
11
|
protected
|
|
7
12
|
|
|
8
13
|
def run
|
|
9
|
-
|
|
14
|
+
operands = Array.wrap_nil(rules)
|
|
15
|
+
return handle_invalid_args if operands.length < 2
|
|
16
|
+
|
|
17
|
+
prev = evaluate(operands[0])
|
|
18
|
+
operands[1..].each do |rule|
|
|
19
|
+
curr = evaluate(rule)
|
|
20
|
+
result = compare(prev, curr)
|
|
21
|
+
return handle_nan if result == :nan
|
|
22
|
+
return false unless result >= 0
|
|
23
|
+
prev = curr
|
|
24
|
+
end
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def compare(a, b)
|
|
31
|
+
# Arrays u objetos → NaN
|
|
32
|
+
return :nan if a.is_a?(Array) || a.is_a?(Hash) || b.is_a?(Array) || b.is_a?(Hash)
|
|
33
|
+
|
|
34
|
+
# Ambos strings → comparación lexicográfica
|
|
35
|
+
if a.is_a?(String) && b.is_a?(String)
|
|
36
|
+
return a <=> b
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Convertir a números para comparar
|
|
40
|
+
num_a = numerify_for_compare(a)
|
|
41
|
+
num_b = numerify_for_compare(b)
|
|
42
|
+
return :nan if num_a.nil? || num_b.nil?
|
|
43
|
+
|
|
44
|
+
num_a <=> num_b
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def numerify_for_compare(value)
|
|
48
|
+
return value.to_f if value.is_a?(Numeric)
|
|
49
|
+
return 0.0 if value == false
|
|
50
|
+
return 1.0 if value == true
|
|
51
|
+
return 0.0 if value.nil?
|
|
52
|
+
return value.to_f if value.is_a?(String) && numeric_string?(value)
|
|
53
|
+
nil # String no numérica
|
|
10
54
|
end
|
|
11
55
|
end
|
|
12
56
|
end
|
|
@@ -6,20 +6,14 @@ module ShinyJsonLogic
|
|
|
6
6
|
class Base < Operations::Base
|
|
7
7
|
def initialize(context)
|
|
8
8
|
super
|
|
9
|
-
collection = rules.any? ? rules[0] : rules
|
|
10
|
-
return handle_nil_collection if collection.nil?
|
|
11
|
-
|
|
12
|
-
if collection.nil?
|
|
13
|
-
@collection = []
|
|
14
|
-
else
|
|
15
|
-
Engine.new(collection, data).tap do |engine|
|
|
16
|
-
call = engine.call
|
|
17
|
-
@collection = Array.wrap(call)
|
|
18
|
-
self.errors = [*self.errors, *engine.errors]
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
9
|
|
|
22
10
|
@filter = rules[1]
|
|
11
|
+
return handle_nil if @filter.nil? && self.class.raise_on_nil_filter?
|
|
12
|
+
|
|
13
|
+
collection = rules.any? ? rules[0] : rules
|
|
14
|
+
return handle_nil if collection.nil?
|
|
15
|
+
|
|
16
|
+
setup_collection(collection)
|
|
23
17
|
end
|
|
24
18
|
|
|
25
19
|
def call
|
|
@@ -47,9 +41,8 @@ module ShinyJsonLogic
|
|
|
47
41
|
private
|
|
48
42
|
|
|
49
43
|
def on_each(_item)
|
|
50
|
-
Engine.new(filter, data)
|
|
51
|
-
|
|
52
|
-
end
|
|
44
|
+
engine = Engine.new(filter, data)
|
|
45
|
+
[engine.call, engine]
|
|
53
46
|
end
|
|
54
47
|
|
|
55
48
|
def on_before_each(item)
|
|
@@ -72,13 +65,29 @@ module ShinyJsonLogic
|
|
|
72
65
|
""
|
|
73
66
|
end
|
|
74
67
|
|
|
75
|
-
def
|
|
68
|
+
def handle_nil
|
|
76
69
|
error = Errors::Base.new(type: "Invalid Arguments")
|
|
77
70
|
self.errors = [error]
|
|
78
71
|
|
|
79
72
|
error.id
|
|
80
73
|
end
|
|
81
74
|
|
|
75
|
+
def setup_collection(collection)
|
|
76
|
+
if collection.nil?
|
|
77
|
+
@collection = []
|
|
78
|
+
else
|
|
79
|
+
@collection = Array.wrap(evaluate(collection))
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.raise_on_nil_filter!
|
|
84
|
+
@raise_on_nil_filter = true
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def self.raise_on_nil_filter?
|
|
88
|
+
@raise_on_nil_filter
|
|
89
|
+
end
|
|
90
|
+
|
|
82
91
|
attr_reader :collection, :filter
|
|
83
92
|
end
|
|
84
93
|
end
|
|
@@ -6,7 +6,13 @@ module ShinyJsonLogic
|
|
|
6
6
|
protected
|
|
7
7
|
|
|
8
8
|
def run
|
|
9
|
-
|
|
9
|
+
result = nil
|
|
10
|
+
Array.wrap_nil(rules).each do |rule|
|
|
11
|
+
Array.wrap_nil(evaluate(rule)).each do |val|
|
|
12
|
+
result = val if result.nil? || val > result
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
result
|
|
10
16
|
end
|
|
11
17
|
end
|
|
12
18
|
end
|
|
@@ -7,9 +7,15 @@ module ShinyJsonLogic
|
|
|
7
7
|
protected
|
|
8
8
|
|
|
9
9
|
def run
|
|
10
|
-
|
|
10
|
+
items = Array.wrap_nil(rules)
|
|
11
|
+
keys = []
|
|
12
|
+
items.each do |rule|
|
|
13
|
+
evaluated = evaluate(rule)
|
|
14
|
+
keys.concat(Array.wrap_nil(evaluated))
|
|
15
|
+
end
|
|
16
|
+
return keys unless data.is_a?(Hash)
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
keys - deep_keys(data)
|
|
13
19
|
end
|
|
14
20
|
|
|
15
21
|
private
|
|
@@ -7,11 +7,13 @@ module ShinyJsonLogic
|
|
|
7
7
|
protected
|
|
8
8
|
|
|
9
9
|
def run
|
|
10
|
-
|
|
10
|
+
min_required = evaluate(rules[0])
|
|
11
|
+
keys = Array.wrap_nil(evaluate(rules[1]))
|
|
12
|
+
return keys unless data.is_a?(Hash) && rules.is_a?(Array)
|
|
11
13
|
|
|
12
|
-
present =
|
|
13
|
-
ctx = { "rules" =>
|
|
14
|
-
present.size >=
|
|
14
|
+
present = keys & data.keys
|
|
15
|
+
ctx = { "rules" => keys, "data" => data, "errors" => errors }
|
|
16
|
+
present.size >= min_required ? [] : Missing.new(ctx).call["result"]
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
end
|
|
@@ -2,7 +2,6 @@ require "shiny_json_logic/operations/base"
|
|
|
2
2
|
require "shiny_json_logic/numericals/with_error_handling"
|
|
3
3
|
require "shiny_json_logic/numericals/numerify"
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
module ShinyJsonLogic
|
|
7
6
|
module Operations
|
|
8
7
|
class Modulo < Base
|
|
@@ -12,10 +11,30 @@ module ShinyJsonLogic
|
|
|
12
11
|
protected
|
|
13
12
|
|
|
14
13
|
def run
|
|
15
|
-
|
|
14
|
+
operands = Array.wrap_nil(rules)
|
|
15
|
+
return handle_no_operators if operands.empty?
|
|
16
16
|
|
|
17
17
|
safe_arithmetic do
|
|
18
|
-
|
|
18
|
+
result = nil
|
|
19
|
+
count = 0
|
|
20
|
+
|
|
21
|
+
each_operand(operands) do |num|
|
|
22
|
+
count += 1
|
|
23
|
+
result = result.nil? ? num : result.remainder(num)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
return handle_no_operators if count < 2
|
|
27
|
+
|
|
28
|
+
result
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def each_operand(operands)
|
|
35
|
+
operands.each do |rule|
|
|
36
|
+
evaluated = evaluate(rule)
|
|
37
|
+
yield numerify(evaluated)
|
|
19
38
|
end
|
|
20
39
|
end
|
|
21
40
|
end
|
|
@@ -11,12 +11,39 @@ module ShinyJsonLogic
|
|
|
11
11
|
protected
|
|
12
12
|
|
|
13
13
|
def run
|
|
14
|
-
|
|
14
|
+
operands = Array.wrap_nil(rules)
|
|
15
|
+
return 1 if operands.empty?
|
|
15
16
|
|
|
16
17
|
safe_arithmetic do
|
|
17
|
-
|
|
18
|
+
result = nil
|
|
19
|
+
count = 0
|
|
20
|
+
|
|
21
|
+
each_operand(operands) do |num|
|
|
22
|
+
return handle_nan if num.nil?
|
|
23
|
+
count += 1
|
|
24
|
+
result = result.nil? ? num.to_f : result * num.to_f
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
return 1 if count == 0
|
|
28
|
+
|
|
29
|
+
result
|
|
18
30
|
end
|
|
19
31
|
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def each_operand(operands)
|
|
36
|
+
operands.each do |rule|
|
|
37
|
+
evaluated = evaluate(rule)
|
|
38
|
+
yield numerify(evaluated)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def numerify(value)
|
|
43
|
+
val = super
|
|
44
|
+
return 0 if val.nil?
|
|
45
|
+
val
|
|
46
|
+
end
|
|
20
47
|
end
|
|
21
48
|
end
|
|
22
49
|
end
|
|
@@ -1,12 +1,56 @@
|
|
|
1
1
|
require "shiny_json_logic/operations/base"
|
|
2
|
+
require "shiny_json_logic/numericals/with_error_handling"
|
|
3
|
+
require "shiny_json_logic/numericals/numerify"
|
|
2
4
|
|
|
3
5
|
module ShinyJsonLogic
|
|
4
6
|
module Operations
|
|
5
7
|
class Smaller < Base
|
|
8
|
+
include Numericals::WithErrorHandling
|
|
9
|
+
include Numericals::Numerify
|
|
10
|
+
|
|
6
11
|
protected
|
|
7
12
|
|
|
8
13
|
def run
|
|
9
|
-
|
|
14
|
+
operands = Array.wrap_nil(rules)
|
|
15
|
+
return handle_invalid_args if operands.length < 2
|
|
16
|
+
|
|
17
|
+
prev = evaluate(operands[0])
|
|
18
|
+
operands[1..].each do |rule|
|
|
19
|
+
curr = evaluate(rule)
|
|
20
|
+
result = compare(prev, curr)
|
|
21
|
+
return handle_nan if result == :nan
|
|
22
|
+
return false unless result == -1
|
|
23
|
+
prev = curr
|
|
24
|
+
end
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def compare(a, b)
|
|
31
|
+
# Arrays u objetos → NaN
|
|
32
|
+
return :nan if a.is_a?(Array) || a.is_a?(Hash) || b.is_a?(Array) || b.is_a?(Hash)
|
|
33
|
+
|
|
34
|
+
# Ambos strings → comparación lexicográfica
|
|
35
|
+
if a.is_a?(String) && b.is_a?(String)
|
|
36
|
+
return a <=> b
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Convertir a números para comparar
|
|
40
|
+
num_a = numerify_for_compare(a)
|
|
41
|
+
num_b = numerify_for_compare(b)
|
|
42
|
+
return :nan if num_a.nil? || num_b.nil?
|
|
43
|
+
|
|
44
|
+
num_a <=> num_b
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def numerify_for_compare(value)
|
|
48
|
+
return value.to_f if value.is_a?(Numeric)
|
|
49
|
+
return 0.0 if value == false
|
|
50
|
+
return 1.0 if value == true
|
|
51
|
+
return 0.0 if value.nil?
|
|
52
|
+
return value.to_f if value.is_a?(String) && numeric_string?(value)
|
|
53
|
+
nil # String no numérica
|
|
10
54
|
end
|
|
11
55
|
end
|
|
12
56
|
end
|
|
@@ -1,12 +1,56 @@
|
|
|
1
1
|
require "shiny_json_logic/operations/base"
|
|
2
|
+
require "shiny_json_logic/numericals/with_error_handling"
|
|
3
|
+
require "shiny_json_logic/numericals/numerify"
|
|
2
4
|
|
|
3
5
|
module ShinyJsonLogic
|
|
4
6
|
module Operations
|
|
5
7
|
class SmallerEqual < Base
|
|
8
|
+
include Numericals::WithErrorHandling
|
|
9
|
+
include Numericals::Numerify
|
|
10
|
+
|
|
6
11
|
protected
|
|
7
12
|
|
|
8
13
|
def run
|
|
9
|
-
|
|
14
|
+
operands = Array.wrap_nil(rules)
|
|
15
|
+
return handle_invalid_args if operands.length < 2
|
|
16
|
+
|
|
17
|
+
prev = evaluate(operands[0])
|
|
18
|
+
operands[1..].each do |rule|
|
|
19
|
+
curr = evaluate(rule)
|
|
20
|
+
result = compare(prev, curr)
|
|
21
|
+
return handle_nan if result == :nan
|
|
22
|
+
return false unless result <= 0
|
|
23
|
+
prev = curr
|
|
24
|
+
end
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def compare(a, b)
|
|
31
|
+
# Arrays u objetos → NaN
|
|
32
|
+
return :nan if a.is_a?(Array) || a.is_a?(Hash) || b.is_a?(Array) || b.is_a?(Hash)
|
|
33
|
+
|
|
34
|
+
# Ambos strings → comparación lexicográfica
|
|
35
|
+
if a.is_a?(String) && b.is_a?(String)
|
|
36
|
+
return a <=> b
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Convertir a números para comparar
|
|
40
|
+
num_a = numerify_for_compare(a)
|
|
41
|
+
num_b = numerify_for_compare(b)
|
|
42
|
+
return :nan if num_a.nil? || num_b.nil?
|
|
43
|
+
|
|
44
|
+
num_a <=> num_b
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def numerify_for_compare(value)
|
|
48
|
+
return value.to_f if value.is_a?(Numeric)
|
|
49
|
+
return 0.0 if value == false
|
|
50
|
+
return 1.0 if value == true
|
|
51
|
+
return 0.0 if value.nil?
|
|
52
|
+
return value.to_f if value.is_a?(String) && numeric_string?(value)
|
|
53
|
+
nil # String no numérica
|
|
10
54
|
end
|
|
11
55
|
end
|
|
12
56
|
end
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
require "shiny_json_logic/operations/base"
|
|
2
|
-
require "shiny_json_logic/
|
|
2
|
+
require "shiny_json_logic/numericals/with_error_handling"
|
|
3
3
|
|
|
4
4
|
module ShinyJsonLogic
|
|
5
5
|
module Operations
|
|
6
6
|
class StrictDifferent < Base
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
include Numericals::WithErrorHandling
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
operands = Array.wrap_nil(rules)
|
|
13
|
+
return handle_invalid_args if operands.length < 2
|
|
14
|
+
|
|
15
|
+
prev = cast(evaluate(operands[0]))
|
|
16
|
+
operands[1..].each do |rule|
|
|
17
|
+
curr = cast(evaluate(rule))
|
|
18
|
+
return false if curr == prev # Si son iguales, !== es false
|
|
19
|
+
prev = curr
|
|
20
|
+
end
|
|
21
|
+
true # Todos los pares consecutivos son diferentes
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def cast(value)
|
|
27
|
+
value.is_a?(Numeric) ? value.to_f : value
|
|
10
28
|
end
|
|
11
29
|
end
|
|
12
30
|
end
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
require "shiny_json_logic/operations/base"
|
|
2
|
+
require "shiny_json_logic/numericals/with_error_handling"
|
|
2
3
|
|
|
3
4
|
module ShinyJsonLogic
|
|
4
5
|
module Operations
|
|
5
6
|
class StrictEqual < Base
|
|
7
|
+
include Numericals::WithErrorHandling
|
|
8
|
+
|
|
6
9
|
protected
|
|
7
10
|
|
|
8
11
|
def run
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
operands = Array.wrap_nil(rules)
|
|
13
|
+
return handle_invalid_args if operands.length < 2
|
|
14
|
+
|
|
15
|
+
first = cast(evaluate(operands[0]))
|
|
16
|
+
operands[1..].each do |rule|
|
|
17
|
+
return false unless cast(evaluate(rule)) == first
|
|
11
18
|
end
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
12
23
|
|
|
13
|
-
|
|
24
|
+
def cast(value)
|
|
25
|
+
value.is_a?(Numeric) ? value.to_f : value
|
|
14
26
|
end
|
|
15
27
|
end
|
|
16
28
|
end
|
|
@@ -6,8 +6,9 @@ module ShinyJsonLogic
|
|
|
6
6
|
protected
|
|
7
7
|
|
|
8
8
|
def run
|
|
9
|
-
str
|
|
10
|
-
|
|
9
|
+
str = evaluate(rules[0]).to_s
|
|
10
|
+
start = evaluate(rules[1]).to_i
|
|
11
|
+
length = rules[2] ? evaluate(rules[2]).to_i : str.length
|
|
11
12
|
start += str.length if start < 0
|
|
12
13
|
finish = length < 0 ? str.length + length : start + length
|
|
13
14
|
|
|
@@ -11,19 +11,37 @@ module ShinyJsonLogic
|
|
|
11
11
|
protected
|
|
12
12
|
|
|
13
13
|
def run
|
|
14
|
+
operands = Array.wrap_nil(rules)
|
|
15
|
+
return handle_no_operators if operands.empty?
|
|
16
|
+
|
|
14
17
|
safe_arithmetic do
|
|
15
|
-
|
|
18
|
+
result = nil
|
|
19
|
+
count = 0
|
|
20
|
+
|
|
21
|
+
each_operand(operands) do |num|
|
|
22
|
+
count += 1
|
|
23
|
+
result = result.nil? ? num : result - num
|
|
24
|
+
end
|
|
16
25
|
|
|
17
|
-
|
|
26
|
+
return handle_no_operators if count == 0
|
|
27
|
+
return result * -1 if count == 1
|
|
28
|
+
|
|
29
|
+
result
|
|
18
30
|
end
|
|
19
31
|
end
|
|
20
32
|
|
|
21
33
|
private
|
|
22
34
|
|
|
35
|
+
def each_operand(operands)
|
|
36
|
+
operands.each do |rule|
|
|
37
|
+
evaluated = evaluate(rule)
|
|
38
|
+
yield numerify(evaluated)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
23
42
|
def numerify(value)
|
|
24
43
|
val = super
|
|
25
44
|
return 0 if val.nil?
|
|
26
|
-
|
|
27
45
|
val
|
|
28
46
|
end
|
|
29
47
|
end
|