jsonschema_rs 0.49.1 → 0.49.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: 9d150c4402ac7014d11674fba8a3e7ae36638e1a671010b4b8494ede16c03858
4
- data.tar.gz: 4af066e13c47db2d317113d3a6454eae0e2ad60f16c52b31648da7889055bef3
3
+ metadata.gz: 48dc9cf6305e242c8a686a6e1439fcc2d05ce1b2738bfdf1eb42394e05f16d03
4
+ data.tar.gz: 9e828ed439bb3180094d3c2cdc1cbc0723ea71d385c2861278c7347493dfd900
5
5
  SHA512:
6
- metadata.gz: 75713f7e5827481f37962d21c00ed968c8386f020ad1ec054f33d742b7036ad13354741f62e35eba0b82eb161be1b189a83f71e3a99f3fceacd917c2f56d334c
7
- data.tar.gz: a7e7405400ba4dbf94954510ab490372c52258c16c61fe423285d73edcf8837e839601d462fe163bc289a040312d5bb32b9c25a7cd78323bf55b96de52abb613
6
+ metadata.gz: d41807f218f18e5435a4ec6e01326f5459076c78afd126844dcd03a982e1006514ec613333eac241853e8b83859410ab723f53ffa185f959cfd6209f8a4c6399
7
+ data.tar.gz: 768c332d2d735999f58bde2a4947568d9e4e7c7cbf818e6ed8ae4177d890810490cf2494b5bfcea547fe7a0c7827775ba83192e465f77207581a9e40d6d21f1f
data/CHANGELOG.md CHANGED
@@ -2,6 +2,42 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.49.3] - 2026-08-02
6
+
7
+ ### Added
8
+
9
+ - Canonicalization of a recursive schema with no finite witness, which now folds to `false`.
10
+ - Canonicalization of `$dynamicRef` and `$recursiveRef`, which resolve through the dynamic scope and stay symbolic like any other reference. A dangling `$dynamicRef` errors rather than staying `Raw`.
11
+ - Canonicalization of `minContains` under `uniqueItems`, where a demand asking for more matches than its own schema has distinct values now folds to `false`.
12
+ - Canonicalization of a Draft 4 `patternProperties` coverage closed by `additionalProperties: false`, spelled as the closed map it was parsed from.
13
+ - Canonicalization of a `oneOf` whose branches repeat, where a repeated branch can never contribute exactly one match.
14
+ - Canonicalization of a `$ref` whose target is an empty schema, which now folds to `false`.
15
+ - Canonicalization of `unevaluatedItems` beside `allOf`, where every branch must pass and so the indexes they evaluate are known without the instance.
16
+ - Canonicalization of `unevaluatedProperties` beside `allOf`, where every branch must pass and so what they evaluate is known without the instance.
17
+ - Canonicalization of a Draft 4 `type` list holding `integer` beside other types with `enum`, which previously modeled only when spelled as an `allOf`.
18
+ - Canonicalization of `patternProperties` patterns matching finitely many keys, such as `^a$` and `^(a|b)$`.
19
+ - Canonicalization of `unevaluatedProperties` and `unevaluatedItems` when no in-place applicator sits beside them.
20
+
21
+ ### Fixed
22
+
23
+ - `additionalItems` values that are not schemas silently ignored beside an array-form `items` (they should fail the build like `additionalProperties`).
24
+ - `additionalItems` beside a boolean `items` rejecting every instance, such as `{"additionalItems": false, "items": false}`.
25
+ - Draft 4 rejecting a size bound at or past `2^64`, such as `{"maxItems": 18446744073709551616}`.
26
+ - An integer past the `f64` range admitted by a fractional bound it exceeds, such as `1e400` under `{"exclusiveMaximum": 0.1}`.
27
+ - A `$ref` at the root of an `$id`-bearing subresource dropped as a self-reference when its pointer matched the one that reached that subresource.
28
+ - Canonicalization reusing one definition's body for a same-named definition in another resource, when the name spells a canonical URI.
29
+ - `unevaluatedItems` counting `prefixItems` as evaluating elements before Draft 2020-12, where it is not a keyword.
30
+
31
+ ### Performance
32
+
33
+ - Up to 70% faster `evaluate`.
34
+
35
+ ## [0.49.2] - 2026-07-28
36
+
37
+ ### Performance
38
+
39
+ - Faster serialization of canonicalized schemas.
40
+
5
41
  ## [0.49.1] - 2026-07-25
6
42
 
7
43
  ### Fixed
@@ -226,7 +262,9 @@
226
262
 
227
263
  - Initial public release
228
264
 
229
- [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.1...HEAD
265
+ [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.3...HEAD
266
+ [0.49.3]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.2...ruby-v0.49.3
267
+ [0.49.2]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.1...ruby-v0.49.2
230
268
  [0.49.1]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.0...ruby-v0.49.1
231
269
  [0.49.0]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.48.5...ruby-v0.49.0
232
270
  [0.48.5]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.48.2...ruby-v0.48.5
data/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb"
3
- version = "0.49.1"
3
+ version = "0.49.3"
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.49.1", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
16
+ jsonschema = { version = "0.49.3", 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.49.1"
696
+ version = "0.49.3"
697
697
  source = "registry+https://github.com/rust-lang/crates.io-index"
698
- checksum = "9cc9116a0f75b7336e55eb2a2a0ddef86c37cadf02924a571751aa123d5a0290"
698
+ checksum = "508004a5500f2e1f68af048f70feea2de86d35ab115d85716530860822aef397"
699
699
  dependencies = [
700
700
  "ahash",
701
701
  "bytecount",
@@ -726,9 +726,9 @@ dependencies = [
726
726
 
727
727
  [[package]]
728
728
  name = "jsonschema-macros"
729
- version = "0.49.1"
729
+ version = "0.49.3"
730
730
  source = "registry+https://github.com/rust-lang/crates.io-index"
731
- checksum = "b78efbcc1da165d63e1944fa687b3c2c09e8e418e9481e25aeada6062160c1bf"
731
+ checksum = "f4e131231bc18676df289bd7634d4353d5b36bced191928bfa2a2dcae91e44a0"
732
732
  dependencies = [
733
733
  "jsonschema-macros-core",
734
734
  "proc-macro2",
@@ -736,9 +736,9 @@ dependencies = [
736
736
 
737
737
  [[package]]
738
738
  name = "jsonschema-macros-core"
739
- version = "0.49.1"
739
+ version = "0.49.3"
740
740
  source = "registry+https://github.com/rust-lang/crates.io-index"
741
- checksum = "10c6550900b4a6be61392b8ddeb62b5c057975371ce93fca76d92542015f98bf"
741
+ checksum = "75803a5014f912d5a8f3c8cc24531d19ea06dfadda75ddf1d15af629f7c8468c"
742
742
  dependencies = [
743
743
  "fancy-regex",
744
744
  "indexmap",
@@ -755,7 +755,7 @@ dependencies = [
755
755
 
756
756
  [[package]]
757
757
  name = "jsonschema-rb-ext"
758
- version = "0.49.1"
758
+ version = "0.49.3"
759
759
  dependencies = [
760
760
  "jsonschema",
761
761
  "magnus",
@@ -768,18 +768,18 @@ dependencies = [
768
768
 
769
769
  [[package]]
770
770
  name = "jsonschema-regex"
771
- version = "0.49.1"
771
+ version = "0.49.3"
772
772
  source = "registry+https://github.com/rust-lang/crates.io-index"
773
- checksum = "628a1f02bda4651d9a6088ee6386a92f0ee96255b0c99e9dfe1be91bf83bd838"
773
+ checksum = "5a8b30cafa78358ae6cd1494a7d6410b89530e28bf567f862c869c667e900d9f"
774
774
  dependencies = [
775
775
  "regex-syntax",
776
776
  ]
777
777
 
778
778
  [[package]]
779
779
  name = "jsonschema-value"
780
- version = "0.49.1"
780
+ version = "0.49.3"
781
781
  source = "registry+https://github.com/rust-lang/crates.io-index"
782
- checksum = "75d94a372f8d81d070fd405065c6b1168d8248d1d6adad073ac708de254698c6"
782
+ checksum = "5526bd381d230af94908d07e6835a33fd82a465e12f5f1e9c81f5c2aa23b3c21"
783
783
  dependencies = [
784
784
  "ahash",
785
785
  "bytecount",
@@ -1132,9 +1132,9 @@ dependencies = [
1132
1132
 
1133
1133
  [[package]]
1134
1134
  name = "referencing"
1135
- version = "0.49.1"
1135
+ version = "0.49.3"
1136
1136
  source = "registry+https://github.com/rust-lang/crates.io-index"
1137
- checksum = "978badf4419c9d0e1bc6e7466e99277f829d768257670c46d88121ca75e34bf7"
1137
+ checksum = "7af3eb523cce0df0af3c30d624b829b2dabd233172b5bc2615fcd03ceae8f746"
1138
1138
  dependencies = [
1139
1139
  "ahash",
1140
1140
  "fluent-uri",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb-ext"
3
- version = "0.49.1"
3
+ version = "0.49.3"
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.49.1", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
13
+ jsonschema = { version = "0.49.3", 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.49.1"
16
+ referencing = "0.49.3"
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.49.1"
4
+ VERSION = "0.49.3"
5
5
  end
data/src/canonical.rs CHANGED
@@ -182,7 +182,11 @@ impl RbCanonicalSchema {
182
182
  additional_properties: view.additional_properties,
183
183
  })
184
184
  .as_value(),
185
+ CanonicalView::Not(schema) => ruby.obj_wrap(NotView { schema: *schema }).as_value(),
186
+ CanonicalView::AllOf(branches) => ruby.obj_wrap(AllOfView { branches }).as_value(),
185
187
  CanonicalView::AnyOf(branches) => ruby.obj_wrap(AnyOfView { branches }).as_value(),
188
+ CanonicalView::OneOf(branches) => ruby.obj_wrap(OneOfView { branches }).as_value(),
189
+ CanonicalView::Reference(uri) => ruby.obj_wrap(ReferenceView { uri }).as_value(),
186
190
  CanonicalView::Raw(schema) => ruby.obj_wrap(RawView { schema }).as_value(),
187
191
  }
188
192
  }
@@ -836,6 +840,147 @@ impl AnyOfView {
836
840
  }
837
841
  }
838
842
 
843
+ /// A value matches iff exactly one branch matches.
844
+ #[derive(magnus::TypedData)]
845
+ #[magnus(class = "JSONSchema::Canonical::OneOfView", free_immediately)]
846
+ pub struct OneOfView {
847
+ branches: Vec<CanonicalSchema>,
848
+ }
849
+
850
+ impl DataTypeFunctions for OneOfView {}
851
+
852
+ impl OneOfView {
853
+ fn branches(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
854
+ let array = ruby.ary_new_capa(rb_self.branches.len());
855
+ for branch in &rb_self.branches {
856
+ array.push(
857
+ ruby.obj_wrap(RbCanonicalSchema {
858
+ inner: branch.clone(),
859
+ })
860
+ .as_value(),
861
+ )?;
862
+ }
863
+ Ok(array.as_value())
864
+ }
865
+
866
+ fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
867
+ let kinds = ruby.ary_new_capa(rb_self.branches.len());
868
+ for branch in &rb_self.branches {
869
+ kinds.push(ruby.sym_new(branch.kind().as_str()).as_value())?;
870
+ }
871
+ Ok(format!(
872
+ "#<JSONSchema::Canonical::OneOfView branches={}>",
873
+ kinds.as_value().inspect()
874
+ ))
875
+ }
876
+
877
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
878
+ let hash = ruby.hash_new();
879
+ hash.aset(ruby.sym_new("branches"), Self::branches(ruby, rb_self)?)?;
880
+ Ok(hash)
881
+ }
882
+ }
883
+
884
+ /// A value matches iff every branch matches.
885
+ #[derive(magnus::TypedData)]
886
+ #[magnus(class = "JSONSchema::Canonical::AllOfView", free_immediately)]
887
+ pub struct AllOfView {
888
+ branches: Vec<CanonicalSchema>,
889
+ }
890
+
891
+ impl DataTypeFunctions for AllOfView {}
892
+
893
+ impl AllOfView {
894
+ fn branches(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
895
+ let array = ruby.ary_new_capa(rb_self.branches.len());
896
+ for branch in &rb_self.branches {
897
+ array.push(
898
+ ruby.obj_wrap(RbCanonicalSchema {
899
+ inner: branch.clone(),
900
+ })
901
+ .as_value(),
902
+ )?;
903
+ }
904
+ Ok(array.as_value())
905
+ }
906
+
907
+ fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
908
+ let kinds = ruby.ary_new_capa(rb_self.branches.len());
909
+ for branch in &rb_self.branches {
910
+ kinds.push(ruby.sym_new(branch.kind().as_str()).as_value())?;
911
+ }
912
+ Ok(format!(
913
+ "#<JSONSchema::Canonical::AllOfView branches={}>",
914
+ kinds.as_value().inspect()
915
+ ))
916
+ }
917
+
918
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
919
+ let hash = ruby.hash_new();
920
+ hash.aset(ruby.sym_new("branches"), Self::branches(ruby, rb_self)?)?;
921
+ Ok(hash)
922
+ }
923
+ }
924
+
925
+ /// The complement of `schema`, preserving a symbolic ref under `not`, conditionals, and `oneOf`.
926
+ #[derive(magnus::TypedData)]
927
+ #[magnus(class = "JSONSchema::Canonical::NotView", free_immediately)]
928
+ pub struct NotView {
929
+ schema: CanonicalSchema,
930
+ }
931
+
932
+ impl DataTypeFunctions for NotView {}
933
+
934
+ impl NotView {
935
+ fn schema(ruby: &Ruby, rb_self: &Self) -> Value {
936
+ ruby.obj_wrap(RbCanonicalSchema {
937
+ inner: rb_self.schema.clone(),
938
+ })
939
+ .as_value()
940
+ }
941
+
942
+ fn inspect(rb_self: &Self) -> String {
943
+ format!(
944
+ "#<JSONSchema::Canonical::NotView schema={}>",
945
+ rb_self.schema.kind().as_str()
946
+ )
947
+ }
948
+
949
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
950
+ let hash = ruby.hash_new();
951
+ hash.aset(ruby.sym_new("schema"), Self::schema(ruby, rb_self))?;
952
+ Ok(hash)
953
+ }
954
+ }
955
+
956
+ /// A symbolic JSON Schema reference.
957
+ #[derive(magnus::TypedData)]
958
+ #[magnus(class = "JSONSchema::Canonical::ReferenceView", free_immediately)]
959
+ pub struct ReferenceView {
960
+ uri: String,
961
+ }
962
+
963
+ impl DataTypeFunctions for ReferenceView {}
964
+
965
+ impl ReferenceView {
966
+ fn uri(rb_self: &Self) -> String {
967
+ rb_self.uri.clone()
968
+ }
969
+
970
+ fn inspect(rb_self: &Self) -> String {
971
+ format!(
972
+ "#<JSONSchema::Canonical::ReferenceView uri={:?}>",
973
+ rb_self.uri
974
+ )
975
+ }
976
+
977
+ fn deconstruct_keys(ruby: &Ruby, rb_self: &Self, _keys: Value) -> Result<RHash, Error> {
978
+ let hash = ruby.hash_new();
979
+ hash.aset(ruby.sym_new("uri"), rb_self.uri.clone())?;
980
+ Ok(hash)
981
+ }
982
+ }
983
+
839
984
  /// Exactly one admitted value.
840
985
  #[derive(magnus::TypedData)]
841
986
  #[magnus(class = "JSONSchema::Canonical::ConstView", free_immediately)]
@@ -1074,6 +1219,29 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
1074
1219
  any_of_view.define_method("inspect", method!(AnyOfView::inspect, 0))?;
1075
1220
  any_of_view.define_method("deconstruct_keys", method!(AnyOfView::deconstruct_keys, 1))?;
1076
1221
 
1222
+ let one_of_view = canonical_module.define_class("OneOfView", ruby.class_object())?;
1223
+ one_of_view.define_method("branches", method!(OneOfView::branches, 0))?;
1224
+ one_of_view.define_method("inspect", method!(OneOfView::inspect, 0))?;
1225
+ one_of_view.define_method("deconstruct_keys", method!(OneOfView::deconstruct_keys, 1))?;
1226
+
1227
+ let all_of_view = canonical_module.define_class("AllOfView", ruby.class_object())?;
1228
+ all_of_view.define_method("branches", method!(AllOfView::branches, 0))?;
1229
+ all_of_view.define_method("inspect", method!(AllOfView::inspect, 0))?;
1230
+ all_of_view.define_method("deconstruct_keys", method!(AllOfView::deconstruct_keys, 1))?;
1231
+
1232
+ let not_view = canonical_module.define_class("NotView", ruby.class_object())?;
1233
+ not_view.define_method("schema", method!(NotView::schema, 0))?;
1234
+ not_view.define_method("inspect", method!(NotView::inspect, 0))?;
1235
+ not_view.define_method("deconstruct_keys", method!(NotView::deconstruct_keys, 1))?;
1236
+
1237
+ let reference_view = canonical_module.define_class("ReferenceView", ruby.class_object())?;
1238
+ reference_view.define_method("uri", method!(ReferenceView::uri, 0))?;
1239
+ reference_view.define_method("inspect", method!(ReferenceView::inspect, 0))?;
1240
+ reference_view.define_method(
1241
+ "deconstruct_keys",
1242
+ method!(ReferenceView::deconstruct_keys, 1),
1243
+ )?;
1244
+
1077
1245
  let raw_view = canonical_module.define_class("RawView", ruby.class_object())?;
1078
1246
  raw_view.define_method("schema", method!(RawView::schema, 0))?;
1079
1247
  raw_view.define_method("inspect", method!(RawView::inspect, 0))?;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonschema_rs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.49.1
4
+ version: 0.49.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dygalo