jsonschema_rs 0.48.2 → 0.49.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7091a24d3c4cae1381d2dcc89844c0c9e2752a04e418a94ded9b3e93656fe9f8
4
- data.tar.gz: c2367c71d93a857f2520dd345e26222608714868e2941a332eb30d78816f75a4
3
+ metadata.gz: 5089bd59db447c9dd706a0fcaf832dac6832d5be6662e988b7a386c8cd31e6b0
4
+ data.tar.gz: ed3f7c83e18c5b8eea755a6a814106693ac729a11325946e878daca82afa0a32
5
5
  SHA512:
6
- metadata.gz: a7dea5681e119df671ac136f7fb9a780e3ac12354487ed763aef6cb7c0f9c68357287a66a17745a2778d78d9aaa5d33faa41de4bbb19f9d7f7b17bbb2285da4a
7
- data.tar.gz: 9c8544d8e5379e5d7013fbed284ef7e932894f23900973a5901a6cb6a40022fbb170bd30ecee04555cf2d512fe3a7a5778e9bff5e809556e9c0a2845a21f70da
6
+ metadata.gz: f15778547054d8aa3e988d34db28fa5144ed87821f4be792120366dc93ff3f2ae908f64610e72047f111f10617187ea6d0debd859be1cb5de11756af8bf874a0
7
+ data.tar.gz: 5d9f288ab525665571492a9e6a8f7846b01dc07f78cee128a998777edcfcb2fb8977dcab97735c4bbbb1634f6f3e350904ec9c1d4e1d987de3c86fefc030f24b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.49.0] - 2026-07-25
6
+
7
+ ### Added
8
+
9
+ - **EXPERIMENTAL**: Schema canonicalization via `jsonschema::canonicalize`. It reduces a reasonable subset of JSON Schemas to their normal forms.
10
+ - Validation of recursive Ruby objects.
11
+
12
+ ### Changed
13
+
14
+ - Invalid UTF-8, unsupported types, and nesting past the depth limit are reported only where a keyword reads the value.
15
+ - A hash keyed by both `:name` and `"name"` counts two properties (it previously collapsed them into one).
16
+
17
+ ### Fixed
18
+
19
+ - `multipleOf` incorrectly accepted integers past `u64` that are not multiples of the divisor.
20
+
21
+ ### Performance
22
+
23
+ - Up to 3x faster validation by working on Ruby objects directly instead of converting them to `serde_json`. [#239](https://github.com/Stranger6667/jsonschema/issues/239)
24
+
25
+ ## [0.48.5] - 2026-07-22
26
+
27
+ ### Performance
28
+
29
+ - Avoid map lookups in some `properties` validators.
30
+ - Faster validation of `{"type": "array", "items": {...}}` schemas.
31
+
5
32
  ## [0.48.2] - 2026-07-21
6
33
 
7
34
  ### Fixed
@@ -192,7 +219,9 @@
192
219
 
193
220
  - Initial public release
194
221
 
195
- [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.48.2...HEAD
222
+ [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.0...HEAD
223
+ [0.49.0]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.48.5...ruby-v0.49.0
224
+ [0.48.5]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.48.2...ruby-v0.48.5
196
225
  [0.48.2]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.48.1...ruby-v0.48.2
197
226
  [0.48.1]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.48.0...ruby-v0.48.1
198
227
  [0.48.0]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.47.0...ruby-v0.48.0
data/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb"
3
- version = "0.48.2"
3
+ version = "0.49.0"
4
4
  edition = "2021"
5
5
  authors = ["Dmitry Dygalo <dmitry@dygalo.dev>"]
6
6
  license = "MIT"
@@ -13,7 +13,7 @@ publish = false
13
13
  crate-type = ["cdylib"]
14
14
 
15
15
  [dependencies]
16
- jsonschema = { version = "0.48.2", default-features = false, features = ["arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
16
+ jsonschema = { version = "0.49.0", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
17
17
  magnus = { version = "0.8", features = ["rb-sys"] }
18
18
  rb-sys = "0.9"
19
19
  serde = { workspace = true }
@@ -693,9 +693,9 @@ dependencies = [
693
693
 
694
694
  [[package]]
695
695
  name = "jsonschema"
696
- version = "0.48.2"
696
+ version = "0.49.0"
697
697
  source = "registry+https://github.com/rust-lang/crates.io-index"
698
- checksum = "39d785c0683d1027839f1ac6a43b6d07c63d58ecd363d8146dda4531d53465a1"
698
+ checksum = "9eb9cf6891f8d15a89f7bcf8e812a62efef1fd8d9e7e4522f455875a1224875a"
699
699
  dependencies = [
700
700
  "ahash",
701
701
  "bytecount",
@@ -708,6 +708,7 @@ dependencies = [
708
708
  "itoa",
709
709
  "jsonschema-macros",
710
710
  "jsonschema-regex",
711
+ "jsonschema-value",
711
712
  "num-bigint",
712
713
  "num-cmp",
713
714
  "num-traits",
@@ -725,9 +726,9 @@ dependencies = [
725
726
 
726
727
  [[package]]
727
728
  name = "jsonschema-macros"
728
- version = "0.48.2"
729
+ version = "0.49.0"
729
730
  source = "registry+https://github.com/rust-lang/crates.io-index"
730
- checksum = "a1c58940755c1f87fc5843b63626867ed8384bc0b6fabf0de2a718ccafb42570"
731
+ checksum = "78fac461293b8d5484a845adbbfaa263ae76616ceae93283baaa4621736f9c54"
731
732
  dependencies = [
732
733
  "jsonschema-macros-core",
733
734
  "proc-macro2",
@@ -735,9 +736,9 @@ dependencies = [
735
736
 
736
737
  [[package]]
737
738
  name = "jsonschema-macros-core"
738
- version = "0.48.2"
739
+ version = "0.49.0"
739
740
  source = "registry+https://github.com/rust-lang/crates.io-index"
740
- checksum = "110e53690c5d5524b69e557bd286b1c6c9743bfcf13c18fd5e3f21a9708737dc"
741
+ checksum = "937a50f77ead02f355faec45d36f0b739da183857002af4f3a2759451dc9aec3"
741
742
  dependencies = [
742
743
  "fancy-regex",
743
744
  "indexmap",
@@ -754,7 +755,7 @@ dependencies = [
754
755
 
755
756
  [[package]]
756
757
  name = "jsonschema-rb-ext"
757
- version = "0.48.2"
758
+ version = "0.49.0"
758
759
  dependencies = [
759
760
  "jsonschema",
760
761
  "magnus",
@@ -767,13 +768,30 @@ dependencies = [
767
768
 
768
769
  [[package]]
769
770
  name = "jsonschema-regex"
770
- version = "0.48.2"
771
+ version = "0.49.0"
771
772
  source = "registry+https://github.com/rust-lang/crates.io-index"
772
- checksum = "917b3be16b2662538aafb55201790561e1f1ad1a0454baf42f33bd9de343778b"
773
+ checksum = "b70811da032e736899c5045ee30f069ba241676739e6ed042c1f9ddd3ad47cde"
773
774
  dependencies = [
774
775
  "regex-syntax",
775
776
  ]
776
777
 
778
+ [[package]]
779
+ name = "jsonschema-value"
780
+ version = "0.49.0"
781
+ source = "registry+https://github.com/rust-lang/crates.io-index"
782
+ checksum = "5ceacf7ad8e9a1f6229a1354dc0ab238855623d219b6abf0a001c138241ec530"
783
+ dependencies = [
784
+ "ahash",
785
+ "bytecount",
786
+ "fraction",
787
+ "magnus",
788
+ "num-bigint",
789
+ "num-cmp",
790
+ "num-traits",
791
+ "rb-sys",
792
+ "serde_json",
793
+ ]
794
+
777
795
  [[package]]
778
796
  name = "lazy_static"
779
797
  version = "1.5.0"
@@ -1114,9 +1132,9 @@ dependencies = [
1114
1132
 
1115
1133
  [[package]]
1116
1134
  name = "referencing"
1117
- version = "0.48.2"
1135
+ version = "0.49.0"
1118
1136
  source = "registry+https://github.com/rust-lang/crates.io-index"
1119
- checksum = "2d2b21a85c07fcf1cb95ff7ab8a687fcd37fa70db59975b5a032abdaadfdf42e"
1137
+ checksum = "cbded44c4882a15738bd1bba376609f679292d758c0b3c389a2ef4a0ea6ce9b7"
1120
1138
  dependencies = [
1121
1139
  "ahash",
1122
1140
  "fluent-uri",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb-ext"
3
- version = "0.48.2"
3
+ version = "0.49.0"
4
4
  edition = "2021"
5
5
  publish = false
6
6
 
@@ -10,10 +10,10 @@ name = "jsonschema_rb"
10
10
  path = "../../src/lib.rs"
11
11
 
12
12
  [dependencies]
13
- jsonschema = { version = "0.48.2", default-features = false, features = ["arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
13
+ jsonschema = { version = "0.49.0", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
14
14
  magnus = { version = "0.8", features = ["rb-sys"] }
15
15
  rb-sys = "0.9"
16
- referencing = "0.48.2"
16
+ referencing = "0.49.0"
17
17
  serde = { version = "1", features = ["derive"] }
18
18
  serde_json = { version = "1", features = ["arbitrary_precision"] }
19
19
  zmij = "1"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JSONSchema
4
- VERSION = "0.48.2"
4
+ VERSION = "0.49.0"
5
5
  end
data/sig/jsonschema.rbs CHANGED
@@ -14,8 +14,159 @@ module JSONSchema
14
14
  # Main use case: deduplicate equivalent JSON Schemas by using a stable string form.
15
15
  def self.to_string: (untyped object) -> String
16
16
  end
17
+
18
+ # Structural discriminant of a canonical schema, one per view class.
19
+ type kind = :multi_type | :typed_group | :string | :integer | :number | :array
20
+ | :object | :const | :enum | :any_of | :true | :false | :raw
21
+
22
+ type view = TrueView | FalseView | MultiTypeView | TypedGroupView | StringView
23
+ | IntegerView | NumberView | ArrayView | ObjectView | AnyOfView
24
+ | ConstView | EnumView | RawView
25
+
26
+ class CanonicalizationError < StandardError
27
+ end
28
+
29
+ class InvalidSchemaType < CanonicalizationError
30
+ end
31
+
32
+ # A schema reduced to canonical form: schemas accepting the same values share one form.
33
+ class CanonicalSchema
34
+ def to_json_schema: () -> untyped
35
+ def draft: () -> JSONSchema::draft
36
+ def kind: () -> kind
37
+ def view: () -> view
38
+ def definitions: () -> Hash[String, CanonicalSchema]
39
+ def satisfiable?: () -> bool
40
+ def inspect: () -> String
41
+ def ==: (untyped other) -> bool
42
+ def eql?: (untyped other) -> bool
43
+ def hash: () -> Integer
44
+ end
45
+
46
+ # Matches any value.
47
+ class TrueView
48
+ end
49
+
50
+ # Matches no value.
51
+ class FalseView
52
+ end
53
+
54
+ # A value matches iff its JSON type is in the set.
55
+ class MultiTypeView
56
+ def types: () -> Array[Symbol]
57
+ def inspect: () -> String
58
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
59
+ end
60
+
61
+ # A value matches iff its JSON type is `type_name` and it satisfies `body`.
62
+ class TypedGroupView
63
+ def type_name: () -> Symbol
64
+ def body: () -> CanonicalSchema
65
+ def inspect: () -> String
66
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
67
+ end
68
+
69
+ # A string value within a length window, matching every pattern.
70
+ class StringView
71
+ def min_length: () -> Integer?
72
+ def max_length: () -> Integer?
73
+ def patterns: () -> Array[String]
74
+ def formats: () -> Array[String]
75
+ def content_media_types: () -> Array[String]
76
+ def content_encodings: () -> Array[String]
77
+ def inspect: () -> String
78
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
79
+ end
80
+
81
+ # A number value within a real interval.
82
+ class NumberView
83
+ def minimum: () -> (Integer | Float)?
84
+ def exclusive_minimum: () -> bool
85
+ def maximum: () -> (Integer | Float)?
86
+ def exclusive_maximum: () -> bool
87
+ def multiple_of: () -> Array[Integer | Float]
88
+ def inspect: () -> String
89
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
90
+ end
91
+
92
+ # An integer value within a closed interval, optionally a multiple of a divisor.
93
+ class IntegerView
94
+ def minimum: () -> Integer?
95
+ def maximum: () -> Integer?
96
+ def multiple_of: () -> Array[Integer | Float]
97
+ def inspect: () -> String
98
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
99
+ end
100
+
101
+ # An array value whose length is within a window.
102
+ class ArrayView
103
+ def min_items: () -> Integer?
104
+ def max_items: () -> Integer?
105
+ def unique_items: () -> bool
106
+ def prefix_items: () -> Array[CanonicalSchema]
107
+ def items: () -> CanonicalSchema?
108
+ def contains: () -> Array[ContainsView]
109
+ def inspect: () -> String
110
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
111
+ end
112
+
113
+ # One `contains` demand of an array; an absent minimum spells the default of one.
114
+ class ContainsView
115
+ def schema: () -> CanonicalSchema
116
+ def min_contains: () -> Integer?
117
+ def max_contains: () -> Integer?
118
+ def inspect: () -> String
119
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
120
+ end
121
+
122
+ # An object value whose property count is within a window.
123
+ class ObjectView
124
+ def min_properties: () -> Integer?
125
+ def max_properties: () -> Integer?
126
+ def required: () -> Array[String]
127
+ def property_names: () -> CanonicalSchema?
128
+ def properties: () -> Hash[String, CanonicalSchema]
129
+ def pattern_properties: () -> Hash[String, CanonicalSchema]
130
+ def inspect: () -> String
131
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
132
+ end
133
+
134
+ # A value matches iff at least one branch matches.
135
+ class AnyOfView
136
+ def branches: () -> Array[CanonicalSchema]
137
+ def inspect: () -> String
138
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
139
+ end
140
+
141
+ # Exactly one admitted value.
142
+ class ConstView
143
+ def value: () -> untyped
144
+ def inspect: () -> String
145
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
146
+ end
147
+
148
+ # A sorted, deduplicated finite set of admitted values.
149
+ class EnumView
150
+ def values: () -> Array[untyped]
151
+ def inspect: () -> String
152
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
153
+ end
154
+
155
+ # A schema the canonical form does not model structurally, kept verbatim.
156
+ class RawView
157
+ def schema: () -> untyped
158
+ def inspect: () -> String
159
+ def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
160
+ end
17
161
  end
18
162
 
163
+ # Reduce a schema to its canonical form.
164
+ def self.canonicalize: (
165
+ untyped schema,
166
+ ?draft: draft?,
167
+ ?validate_formats: bool?
168
+ ) -> Canonical::CanonicalSchema
169
+
19
170
  # Create a validator with auto-detected draft version.
20
171
  #
21
172
  # @param schema The JSON Schema (Hash or JSON string)