schemurai 2.2.2 → 2.3.0
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/README.md +14 -3
- data/ext/schemurai_native/Cargo.lock +99 -0
- data/ext/schemurai_native/Cargo.toml +21 -0
- data/ext/schemurai_native/build.rs +35 -0
- data/ext/schemurai_native/extconf.rb +63 -0
- data/ext/schemurai_native/glue.c +639 -0
- data/ext/schemurai_native/protocol.def +63 -0
- data/ext/schemurai_native/protocol.h +10 -0
- data/ext/schemurai_native/src/content.rs +574 -0
- data/ext/schemurai_native/src/diagnostics.rs +965 -0
- data/ext/schemurai_native/src/format.rs +357 -0
- data/ext/schemurai_native/src/lib.rs +2376 -0
- data/ext/schemurai_native/src/number.rs +1055 -0
- data/ext/schemurai_native/src/pattern.rs +288 -0
- data/ext/schemurai_native/src/scope.rs +210 -0
- data/ext/schemurai_native/src/tracking.rs +532 -0
- data/lib/schemurai/backend.rb +2 -1
- data/lib/schemurai/native/diagnostics.rb +52 -0
- data/lib/schemurai/native/evaluator.rb +32 -0
- data/lib/schemurai/version.rb +1 -1
- data/lib/schemurai/vm/evaluator.rb +28 -32
- data/lib/schemurai.rb +8 -7
- data/sig/schemurai.rbs +1 -1
- metadata +22 -4
|
@@ -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
|
-
|
|
17
|
-
|
|
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
|
|
32
|
+
@evaluated_properties.add(name)
|
|
30
33
|
self
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
def record_item(index)
|
|
34
|
-
@evaluated_items
|
|
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
|
-
|
|
42
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
903
|
+
add_error("not") { Internal::ErrorMessage.not } if trial(operand, value).valid?
|
|
903
904
|
when :conditional
|
|
904
|
-
condition =
|
|
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
|
data/lib/schemurai.rb
CHANGED
|
@@ -72,19 +72,19 @@ module Schemurai
|
|
|
72
72
|
# Register every external schema with +schemas:+ before compiling. A registry
|
|
73
73
|
# can be made shareable once registration and compilation are complete.
|
|
74
74
|
class SchemaRegistry
|
|
75
|
-
# The selected backend,
|
|
75
|
+
# The selected backend, +:ruby+, +:vm+, or +:native+.
|
|
76
76
|
attr_reader :backend
|
|
77
77
|
|
|
78
78
|
# Creates a registry.
|
|
79
79
|
#
|
|
80
80
|
# +schemas+ maps absolute URI strings to JSON-shaped Ruby schemas. Pass
|
|
81
81
|
# +validate_schema: true+ to validate every registered and compiled schema
|
|
82
|
-
# against its meta-schema. +backend+ accepts +:ruby+, +:vm+, or +:default+.
|
|
82
|
+
# against its meta-schema. +backend+ accepts +:ruby+, +:vm+, +:native+, or +:default+.
|
|
83
83
|
def initialize(schemas: {}, validate_schema: false, backend: Backend.requested)
|
|
84
84
|
@backend = Backend.resolve(backend)
|
|
85
85
|
@validate_schema = validate_schema
|
|
86
86
|
@graph = Internal::SchemaGraph.new(schemas: schemas)
|
|
87
|
-
@compiler = VM::Compiler.new(@graph) if @backend
|
|
87
|
+
@compiler = VM::Compiler.new(@graph) if %i[vm native].include?(@backend)
|
|
88
88
|
schemas.each_value { |schema| validate_schema!(schema) } if validate_schema?
|
|
89
89
|
end
|
|
90
90
|
|
|
@@ -150,7 +150,8 @@ module Schemurai
|
|
|
150
150
|
private def build_validator(root, content:, format:)
|
|
151
151
|
evaluator = if @compiler
|
|
152
152
|
program = @compiler.compile(root)
|
|
153
|
-
|
|
153
|
+
evaluator_class = (@backend == :native) ? Native::Evaluator : VM::Evaluator
|
|
154
|
+
evaluator_class.new(@graph, @compiler, program, content: content, format: format)
|
|
154
155
|
else
|
|
155
156
|
Internal::Evaluator.new(@graph, root, content: content, format: format)
|
|
156
157
|
end
|
|
@@ -177,7 +178,7 @@ module Schemurai
|
|
|
177
178
|
@evaluator = evaluator
|
|
178
179
|
end
|
|
179
180
|
|
|
180
|
-
# The backend reported by the evaluator,
|
|
181
|
+
# The backend reported by the evaluator, +:ruby+, +:vm+, or +:native+.
|
|
181
182
|
def backend
|
|
182
183
|
@evaluator.backend
|
|
183
184
|
end
|
|
@@ -193,7 +194,7 @@ module Schemurai
|
|
|
193
194
|
end
|
|
194
195
|
end
|
|
195
196
|
|
|
196
|
-
# Returns the backend selected by SCHEMURAI_BACKEND,
|
|
197
|
+
# Returns the backend selected by SCHEMURAI_BACKEND, +:ruby+, +:vm+, or +:native+.
|
|
197
198
|
module_function def backend
|
|
198
199
|
Backend.resolve
|
|
199
200
|
end
|
|
@@ -202,7 +203,7 @@ module Schemurai
|
|
|
202
203
|
#
|
|
203
204
|
# +schemas+ maps external URI strings to schemas. +base_uri+ supplies the
|
|
204
205
|
# schema's base URI. Optional content and format assertions are disabled by
|
|
205
|
-
# default. +backend+ accepts +:ruby+, +:vm+, or +:default+.
|
|
206
|
+
# default. +backend+ accepts +:ruby+, +:vm+, +:native+, or +:default+.
|
|
206
207
|
module_function def compile(schema, schemas: {}, base_uri: nil, content: false, format: false, validate_schema: false, backend: Backend.requested)
|
|
207
208
|
SchemaRegistry.new(schemas: schemas, validate_schema: validate_schema, backend: backend).compile(
|
|
208
209
|
schema,
|
data/sig/schemurai.rbs
CHANGED
|
@@ -9,7 +9,7 @@ module Schemurai
|
|
|
9
9
|
type schemas = Hash[String, schema]
|
|
10
10
|
|
|
11
11
|
# A resolved evaluator backend.
|
|
12
|
-
type backend = :ruby | :vm
|
|
12
|
+
type backend = :ruby | :vm | :native
|
|
13
13
|
|
|
14
14
|
# A backend accepted when configuring a validator.
|
|
15
15
|
type backend_selection = backend | :default
|
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.
|
|
4
|
+
version: 2.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kuya KOHARA (oakcask)
|
|
@@ -28,13 +28,29 @@ description: Validates Ruby values against JSON Schema Draft 7, 2019-09, and 202
|
|
|
28
28
|
email:
|
|
29
29
|
- kuya.kohara@gmail.com
|
|
30
30
|
executables: []
|
|
31
|
-
extensions:
|
|
31
|
+
extensions:
|
|
32
|
+
- ext/schemurai_native/extconf.rb
|
|
32
33
|
extra_rdoc_files:
|
|
33
34
|
- LICENSE
|
|
34
35
|
- README.md
|
|
35
36
|
files:
|
|
36
37
|
- LICENSE
|
|
37
38
|
- README.md
|
|
39
|
+
- ext/schemurai_native/Cargo.lock
|
|
40
|
+
- ext/schemurai_native/Cargo.toml
|
|
41
|
+
- ext/schemurai_native/build.rs
|
|
42
|
+
- ext/schemurai_native/extconf.rb
|
|
43
|
+
- ext/schemurai_native/glue.c
|
|
44
|
+
- ext/schemurai_native/protocol.def
|
|
45
|
+
- ext/schemurai_native/protocol.h
|
|
46
|
+
- ext/schemurai_native/src/content.rs
|
|
47
|
+
- ext/schemurai_native/src/diagnostics.rs
|
|
48
|
+
- ext/schemurai_native/src/format.rs
|
|
49
|
+
- ext/schemurai_native/src/lib.rs
|
|
50
|
+
- ext/schemurai_native/src/number.rs
|
|
51
|
+
- ext/schemurai_native/src/pattern.rs
|
|
52
|
+
- ext/schemurai_native/src/scope.rs
|
|
53
|
+
- ext/schemurai_native/src/tracking.rs
|
|
38
54
|
- lib/schemurai.rb
|
|
39
55
|
- lib/schemurai/backend.rb
|
|
40
56
|
- lib/schemurai/dialect.rb
|
|
@@ -50,6 +66,8 @@ files:
|
|
|
50
66
|
- lib/schemurai/meta_schemas/draft2019_09.rb
|
|
51
67
|
- lib/schemurai/meta_schemas/draft2020_12.rb
|
|
52
68
|
- lib/schemurai/meta_schemas/draft7.rb
|
|
69
|
+
- lib/schemurai/native/diagnostics.rb
|
|
70
|
+
- lib/schemurai/native/evaluator.rb
|
|
53
71
|
- lib/schemurai/schema_domain.rb
|
|
54
72
|
- lib/schemurai/schema_graph.rb
|
|
55
73
|
- lib/schemurai/schema_node.rb
|
|
@@ -64,7 +82,7 @@ licenses:
|
|
|
64
82
|
metadata:
|
|
65
83
|
homepage_uri: https://github.com/oakcask/schemurai
|
|
66
84
|
source_code_uri: https://github.com/oakcask/schemurai/tree/main
|
|
67
|
-
documentation_uri: https://rubydoc.info/gems/schemurai/2.
|
|
85
|
+
documentation_uri: https://rubydoc.info/gems/schemurai/2.3.0
|
|
68
86
|
rubygems_mfa_required: 'true'
|
|
69
87
|
rdoc_options:
|
|
70
88
|
- "--main"
|
|
@@ -90,5 +108,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
90
108
|
requirements: []
|
|
91
109
|
rubygems_version: 4.0.20
|
|
92
110
|
specification_version: 4
|
|
93
|
-
summary: A fast, Ractor-safe
|
|
111
|
+
summary: A fast, Ractor-safe JSON Schema Draft 7+ validator
|
|
94
112
|
test_files: []
|