schemurai 2.2.2 → 2.2.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: 163dbc9593611cce4f28183766bd5e17a08387a54883c17a502a198eb010ad36
4
- data.tar.gz: aa3d5f90db227194179023b31043cf36b4597e4af5f1e2209b2846e9c36f9044
3
+ metadata.gz: c4620544f45920ada46eda1beff7cbb6461fb1633031f78d2964c4e963716d82
4
+ data.tar.gz: b0a66f4e369181d9182a10715d1622924ebac68cfe32a1169b844714a7b6a038
5
5
  SHA512:
6
- metadata.gz: 5f5ba215dde91e1bf364ff6ebbbebb7ea40b284e3908cfcb578d48aad2174c34e5cf6d9fd121947bb54f8b2cf0fad626e629ed94d6b4a52ab41ba84ad7dfbc55
7
- data.tar.gz: 4efa97250aad095e414eb230310ae580bbd029b834aa11322cab8da0b19df7a1fb6703240ee0439fd4abe788fcfa47c918ac92806bef174d38d0110bb35cc934
6
+ metadata.gz: b6dd9a631fa90e9600e0a60ba4e2ecfca492497a69376a11801cf1a4bfb799fb71eea3546f417b394279b7c3795ace0d2ff8422c8fa8c0b9c9cf6e7530ca8f86
7
+ data.tar.gz: b8b2e1bdaccdfc420b1aa2cec9fc2bef856157d450ccb547dcf230693b4b959baa77f9901b9df920c5c73bd6ef982b468249655397c0160e55c3b57772b1c2c5
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Schemurai
4
4
  # The installed Schemurai version.
5
- VERSION = "2.2.2"
5
+ VERSION = "2.2.3"
6
6
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "base64"
4
4
  require "json"
5
+ require "set" # rubocop:disable Lint/RedundantRequireStatement -- Required on Ruby 3.4.
5
6
  require_relative "../evaluation"
6
7
  require_relative "../error_message"
7
8
  require_relative "../unique_items"
@@ -13,8 +14,10 @@ module Schemurai
13
14
  attr_reader :evaluated_properties, :evaluated_items
14
15
 
15
16
  def initialize
16
- @evaluated_properties = []
17
- @evaluated_items = []
17
+ # Applicators can overlap. Array membership makes collecting and merging
18
+ # their annotations quadratic in the number of instance locations.
19
+ @evaluated_properties = Set.new
20
+ @evaluated_items = Set.new
18
21
  end
19
22
 
20
23
  def valid? = true
@@ -26,26 +29,24 @@ module Schemurai
26
29
  end
27
30
 
28
31
  def record_property(name)
29
- @evaluated_properties << name unless @evaluated_properties.include?(name)
32
+ @evaluated_properties.add(name)
30
33
  self
31
34
  end
32
35
 
33
36
  def record_item(index)
34
- @evaluated_items << index unless @evaluated_items.include?(index)
37
+ @evaluated_items.add(index)
35
38
  self
36
39
  end
37
40
 
38
41
  def merge(other)
39
42
  return Evaluation.invalid unless other.valid?
40
43
 
41
- merge_locations(@evaluated_properties, other.evaluated_properties)
42
- merge_locations(@evaluated_items, other.evaluated_items)
44
+ properties = other.evaluated_properties
45
+ items = other.evaluated_items
46
+ @evaluated_properties.merge(properties) unless properties.empty?
47
+ @evaluated_items.merge(items) unless items.empty?
43
48
  self
44
49
  end
45
-
46
- private def merge_locations(target, locations)
47
- locations.each { |location| target << location unless target.include?(location) }
48
- end
49
50
  end
50
51
  private_constant :EvaluationBuffer
51
52
 
@@ -652,7 +653,7 @@ module Schemurai
652
653
  matched = nil
653
654
  index = 0
654
655
  while index < value.length
655
- (matched ||= []) << index if trial_at(contains, value[index], index, "contains").valid?
656
+ (matched ||= []) << index if trial(contains, value[index]).valid?
656
657
  index += 1
657
658
  end
658
659
  matched_count = matched ? matched.length : 0
@@ -873,7 +874,7 @@ module Schemurai
873
874
  matches = 0
874
875
  index = 0
875
876
  while index < operand.length
876
- result = trial_at(operand[index], value, MISSING_SEGMENT, "anyOf", index)
877
+ result = trial(operand[index], value)
877
878
  if result.valid?
878
879
  matches += 1
879
880
  evaluation = evaluation.merge(result)
@@ -886,7 +887,7 @@ module Schemurai
886
887
  matched_evaluation = nil
887
888
  index = 0
888
889
  while index < operand.length
889
- result = trial_at(operand[index], value, MISSING_SEGMENT, "oneOf", index)
890
+ result = trial(operand[index], value)
890
891
  if result.valid?
891
892
  matches += 1
892
893
  matched_evaluation = result
@@ -899,9 +900,9 @@ module Schemurai
899
900
  add_error("oneOf") { Internal::ErrorMessage.one_of(matches) }
900
901
  end
901
902
  when :not
902
- add_error("not") { Internal::ErrorMessage.not } if trial_at(operand, value, MISSING_SEGMENT, "not").valid?
903
+ add_error("not") { Internal::ErrorMessage.not } if trial(operand, value).valid?
903
904
  when :conditional
904
- condition = trial_at(operand.condition, value, MISSING_SEGMENT, "if")
905
+ condition = trial(operand.condition, value)
905
906
  condition_valid = condition.valid?
906
907
  evaluation = evaluation.merge(condition) if condition_valid
907
908
  if condition_valid && operand.then_branch
@@ -916,12 +917,24 @@ module Schemurai
916
917
  private def trial(program, value)
917
918
  saved_errors = @errors
918
919
  saved_count = @error_count
920
+ saved_instance_path = @instance_path
919
921
  @errors = nil
920
922
  @error_count = 0
923
+ # Trials retain annotations, but discard errors. Descendants therefore
924
+ # need neither instance nor schema paths until the trial has returned.
925
+ if saved_instance_path
926
+ saved_schema_path = @schema_path
927
+ @instance_path = nil
928
+ @schema_path = nil
929
+ end
921
930
  evaluate(program, value)
922
931
  ensure
923
932
  @errors = saved_errors
924
933
  @error_count = saved_count
934
+ if saved_instance_path
935
+ @instance_path = saved_instance_path
936
+ @schema_path = saved_schema_path
937
+ end
925
938
  end
926
939
 
927
940
  private def evaluate_at(program, instance, instance_segment, schema_segment, child_segment = MISSING_SEGMENT)
@@ -949,23 +962,6 @@ module Schemurai
949
962
  @instance_path.pop unless instance_segment.equal?(MISSING_SEGMENT)
950
963
  end
951
964
 
952
- private def trial_at(program, instance, instance_segment, schema_segment, child_segment = MISSING_SEGMENT)
953
- return trial(program, instance) unless @instance_path
954
-
955
- trial_at_with_path(program, instance, instance_segment, schema_segment, child_segment)
956
- end
957
-
958
- private def trial_at_with_path(program, instance, instance_segment, schema_segment, child_segment)
959
- @instance_path << instance_segment unless instance_segment.equal?(MISSING_SEGMENT)
960
- @schema_path << schema_segment
961
- @schema_path << child_segment unless child_segment.equal?(MISSING_SEGMENT)
962
- trial(program, instance)
963
- ensure
964
- @schema_path.pop unless child_segment.equal?(MISSING_SEGMENT)
965
- @schema_path.pop
966
- @instance_path.pop unless instance_segment.equal?(MISSING_SEGMENT)
967
- end
968
-
969
965
  private def add_error(keyword, message = nil, append_keyword: true)
970
966
  @error_count += 1
971
967
  return false unless @errors
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schemurai
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kuya KOHARA (oakcask)
@@ -64,7 +64,7 @@ licenses:
64
64
  metadata:
65
65
  homepage_uri: https://github.com/oakcask/schemurai
66
66
  source_code_uri: https://github.com/oakcask/schemurai/tree/main
67
- documentation_uri: https://rubydoc.info/gems/schemurai/2.2.2
67
+ documentation_uri: https://rubydoc.info/gems/schemurai/2.2.3
68
68
  rubygems_mfa_required: 'true'
69
69
  rdoc_options:
70
70
  - "--main"