shiny_json_logic 0.3.0 → 0.3.1

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: df6cbb1873a1d4237a634ab972f9da4f2e1b56012f0e9353e34c723746f75655
4
- data.tar.gz: b62ce7480cdbab13df690836b3c837b96b360d08fb6cd0c86ee8e743222234bc
3
+ metadata.gz: 4f62f75b8b9279af811dddcc9a97049550d16f711d33bda0e727e5b4adb36d2d
4
+ data.tar.gz: 596cc8713677361a03805ee566c6684b406526b43c3ad9ba23748283753519f2
5
5
  SHA512:
6
- metadata.gz: cb846733714d95672c98d615c1474582e5516d13e02becbe13a9839d7571d7f2792235595777464b53c5e4173ea8af49d5d721d09283bfa72ade52f231bb74f7
7
- data.tar.gz: 121d271417ace9b145dfc92861e7857ff8c22eb859a7a8d9f2d8ff6b37708a1ee3c55a22f60cf925c1826c41622012848a2a54dd3f4afc9b8084b4ae6424a8e1
6
+ metadata.gz: 34871c34a9999116eaca7af2d1aacf7a41f7527f5181d17bff57aa85d358b44a327a4c8ec03a7c0b2990dc3f3c5c70efd12cc4935e9d72bd0a8d435d2677ba8f
7
+ data.tar.gz: 4156b07eefc2419d34a080d5d1f1d3e570a6536d9a0ca3d16f20fe490e0126c843b10303089336ba3b8132628d71527ec7ef94ec2adc2b7a5acd180d7dc7a1c5
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
+ ## [0.3.1] - 2026-02-23
5
+ ### Changed
6
+ - Removes operations validation pass for optimization purposes.
7
+ - Refactors Truthiness module for case/when in order to improve performance.
8
+
9
+ ### Added
10
+ - Adds `Utils::DataHash` to differentiate context objects from rule objects allowing operation validity on the fly.
11
+
4
12
  ## [0.3.0] - 2026-02-21
5
13
  ### Changed
6
14
  - Refactors internal architecture to improve performance by removing instantiation of operations.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shiny_json_logic (0.3.0)
4
+ shiny_json_logic (0.3.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -1,21 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "shiny_json_logic/operator_solver"
4
+ require "shiny_json_logic/utils/data_hash"
4
5
 
5
6
  module ShinyJsonLogic
6
7
  module Engine
7
8
  OPERATIONS = OperatorSolver::SOLVERS
8
9
 
9
10
  def self.call(rule, scope_stack)
10
- if rule.is_a?(Hash)
11
+ if rule.is_a?(Utils::DataHash)
12
+ rule
13
+ elsif rule.is_a?(Hash)
11
14
  return rule if rule.empty?
12
15
 
13
- operation, args = rule.to_a.first
16
+ raise Errors::UnknownOperator if rule.size > 1
17
+
18
+ operation, args = rule.first
14
19
  operation_key = operation.to_s
15
-
16
- return rule unless OPERATIONS.key?(operation_key)
17
20
 
18
- OPERATIONS.fetch(operation_key).call(args, scope_stack)
21
+ raise Errors::UnknownOperator unless OPERATIONS.key?(operation_key)
22
+
23
+ OPERATIONS[operation_key].call(args, scope_stack)
19
24
  elsif rule.is_a?(Array)
20
25
  rule.map { |val| call(val, scope_stack) }
21
26
  else
@@ -24,3 +29,4 @@ module ShinyJsonLogic
24
29
  end
25
30
  end
26
31
  end
32
+
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "shiny_json_logic/operations/base"
4
+ require "shiny_json_logic/utils/data_hash"
4
5
 
5
6
  module ShinyJsonLogic
6
7
  module Operations
@@ -10,7 +11,7 @@ module ShinyJsonLogic
10
11
 
11
12
  # {"val": []} or {"val": null} - return current scope
12
13
  if raw_keys.empty? || raw_keys == [nil]
13
- return scope_stack.current
14
+ return Utils::DataHash.wrap(scope_stack.current)
14
15
  end
15
16
 
16
17
  # Check if first element is an array (scope navigation syntax)
@@ -23,13 +24,13 @@ module ShinyJsonLogic
23
24
  evaluated_keys = remaining_keys.map { |rule| evaluate(rule, scope_stack) }
24
25
 
25
26
  levels = level_indicator.abs
26
- return scope_stack.resolve(levels, *evaluated_keys)
27
+ return Utils::DataHash.wrap(scope_stack.resolve(levels, *evaluated_keys))
27
28
  end
28
29
 
29
30
  # Normal case: {"val": "key"} or {"val": ["key1", "key2"]}
30
31
  keys = raw_keys.map { |rule| evaluate(rule, scope_stack) }
31
32
  current_data = scope_stack.current
32
- dig_value(current_data, keys)
33
+ Utils::DataHash.wrap(dig_value(current_data, keys))
33
34
  end
34
35
 
35
36
  def self.dig_value(data, keys)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "shiny_json_logic/truthy"
4
4
  require "shiny_json_logic/operations/base"
5
+ require "shiny_json_logic/utils/data_hash"
5
6
 
6
7
  module ShinyJsonLogic
7
8
  module Operations
@@ -12,10 +13,13 @@ module ShinyJsonLogic
12
13
  default = items[1] ? evaluate(items[1], scope_stack) : nil
13
14
  current_data = scope_stack.current
14
15
 
15
- return current_data if key.nil? || key == ""
16
+ if key.nil? || key == ""
17
+ return Utils::DataHash.wrap(current_data)
18
+ end
16
19
 
17
20
  result = fetch_value(current_data, key)
18
- result.nil? ? default : result
21
+ result = result.nil? ? default : result
22
+ Utils::DataHash.wrap(result)
19
23
  rescue
20
24
  default || scope_stack.current
21
25
  end
@@ -5,13 +5,15 @@
5
5
  module ShinyJsonLogic
6
6
  module Truthy
7
7
  def self.call(subject)
8
- return subject if [true, false].include? subject
9
- return !subject.zero? if subject.is_a? Numeric
10
- return subject.any? if subject.is_a? Array
11
- return !subject.empty? if subject.is_a? String
12
- return subject.keys.any? if subject.is_a? Hash
13
-
14
- !subject.nil?
8
+ case subject
9
+ when true, false then subject
10
+ when Numeric then !subject.zero?
11
+ when String then !subject.empty?
12
+ when Array then subject.any?
13
+ when Hash then !subject.empty?
14
+ when NilClass then false
15
+ else true
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ShinyJsonLogic
4
+ module Utils
5
+ # A Hash subclass that marks its contents as user data (result of var/val).
6
+ # The Engine uses this to skip operator validation for these values.
7
+ class DataHash < Hash
8
+ def self.wrap(obj)
9
+ return obj unless obj.is_a?(Hash)
10
+ return obj if obj.is_a?(DataHash)
11
+
12
+ result = new
13
+ obj.each { |k, v| result[k] = v }
14
+ result
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ShinyJsonLogic
4
- VERSION = "0.3.0"
4
+ VERSION = "0.3.1"
5
5
  end
@@ -11,8 +11,6 @@ require "shiny_json_logic/scope_stack"
11
11
 
12
12
  module ShinyJsonLogic
13
13
  def self.apply(rule, data = {})
14
- validate_operators!(rule)
15
-
16
14
  normalized_data = deep_stringify_keys(data || {})
17
15
  scope_stack = ScopeStack.new(normalized_data)
18
16
  Engine.call(rule, scope_stack)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shiny_json_logic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luis Moyano
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-02-21 00:00:00.000000000 Z
11
+ date: 2026-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -177,6 +177,7 @@ files:
177
177
  - lib/shiny_json_logic/scope_stack.rb
178
178
  - lib/shiny_json_logic/truthy.rb
179
179
  - lib/shiny_json_logic/utils/array.rb
180
+ - lib/shiny_json_logic/utils/data_hash.rb
180
181
  - lib/shiny_json_logic/version.rb
181
182
  - results/ruby.json
182
183
  - shiny_json_logic.gemspec