jsonschema_rs 0.49.3 → 0.49.5

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: 48dc9cf6305e242c8a686a6e1439fcc2d05ce1b2738bfdf1eb42394e05f16d03
4
- data.tar.gz: 9e828ed439bb3180094d3c2cdc1cbc0723ea71d385c2861278c7347493dfd900
3
+ metadata.gz: 14182b3d65f8580de3c3c3b3dab17d0709a70e56b93b519a2095f0d87bbda232
4
+ data.tar.gz: c43c5b754ef7a41ff8ce3d06ab79f1f29854967446ee6efb76282af7c0186e98
5
5
  SHA512:
6
- metadata.gz: d41807f218f18e5435a4ec6e01326f5459076c78afd126844dcd03a982e1006514ec613333eac241853e8b83859410ab723f53ffa185f959cfd6209f8a4c6399
7
- data.tar.gz: 768c332d2d735999f58bde2a4947568d9e4e7c7cbf818e6ed8ae4177d890810490cf2494b5bfcea547fe7a0c7827775ba83192e465f77207581a9e40d6d21f1f
6
+ metadata.gz: 503c06fb04a59e9ca5e38eeb0c360741a9d6a409e4dce784ade9babe4514f19fb1f4668b9f21538e661c5bed1d76600cd32ec92bd4c7d1daa8a6e147de4b3607
7
+ data.tar.gz: 53b2d54cbbb81a4b2ccba5eaa7a8cf8144f1597c3ccbf0abf55ba0fbee189a85634a936a5571af77d64e4a9351c04ec57f41867decb15b1404beeb93bc7a0abc
data/CHANGELOG.md CHANGED
@@ -2,6 +2,48 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.49.5] - 2026-08-05
6
+
7
+ ### Added
8
+
9
+ - Canonicalization of `not` an integer schema under Draft 4, which the number leaf carries as barred integers.
10
+ - Canonicalization of `not` a `multipleOf`, which numeric leaves carry as barred divisors.
11
+ - Canonicalization of `not` an integer schema, where a barred divisor of one spells the non-integer numbers.
12
+ - Canonicalization of `not` a `pattern`, which string leaves carry as barred patterns.
13
+ - Canonicalization of `not` a typed value set under Draft 4, such as `{"type": "integer", "enum": [1, 2]}`.
14
+ - `CanonicalSchema#is_subset_of`, whether the other schema admits every value this one admits.
15
+ - Canonicalization of a reference cycle carrying no assertion, which admits every value.
16
+
17
+ ### Fixed
18
+
19
+ - `CanonicalSchema#is_subset_of` failing to prove a union of array branches a subset of itself.
20
+ - Two spellings of one number canonicalizing to different texts when the fraction exceeds the expansion cap.
21
+ - Numeric bounds and `multipleOf` comparing values through a lossy `f64` conversion, such as `1e-400` passing `{"maximum": 0}`.
22
+
23
+ ## [0.49.4] - 2026-08-04
24
+
25
+ ### Added
26
+
27
+ - Canonicalization of `not` a string format, which the string leaf carries as barred formats.
28
+ - Canonicalization of `not` an existential demand, which an array fails exactly when no element matches.
29
+ - Canonicalization of `not` a string value set, which the string leaf carries as excluded values.
30
+ - Canonicalization of `unevaluatedItems` beside `contains`, where the elements it matches are evaluated and the tail admits either.
31
+ - Canonicalization of `unevaluated*` beside `anyOf` or `oneOf`, where every branch evaluating the same keys or indexes pins what is left over.
32
+ - Canonicalization of `not` an array element schema, which an array fails exactly when one element violates it.
33
+ - `CanonicalSchema#intersect`, the values both schemas admit.
34
+ - `CanonicalSchema#negate`, the values a schema rejects.
35
+ - `CanonicalSchema#definition`, one reference target by URI.
36
+
37
+ ### Fixed
38
+
39
+ - An integer past `i64` admitted by a fractional bound `f64` rounds it onto, such as `-10000000000000000000000000` under `{"maximum": -10000000000000000000000000.1}`.
40
+ - An integer past `2^53` admitted by a bound `f64` rounds onto it, such as `9007199254740992` under `{"minimum": 9007199254740993}`.
41
+ - A `contains` subschema beside both `minContains` and `maxContains` overwriting a sibling keyword of the same name, such as `items`.
42
+
43
+ ### Performance
44
+
45
+ - `CanonicalSchema` hashing and equality cost the node instead of the whole document.
46
+
5
47
  ## [0.49.3] - 2026-08-02
6
48
 
7
49
  ### Added
@@ -262,7 +304,9 @@
262
304
 
263
305
  - Initial public release
264
306
 
265
- [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.3...HEAD
307
+ [Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.5...HEAD
308
+ [0.49.5]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.4...ruby-v0.49.5
309
+ [0.49.4]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.3...ruby-v0.49.4
266
310
  [0.49.3]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.2...ruby-v0.49.3
267
311
  [0.49.2]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.1...ruby-v0.49.2
268
312
  [0.49.1]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.49.0...ruby-v0.49.1
data/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb"
3
- version = "0.49.3"
3
+ version = "0.49.5"
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.3", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
16
+ jsonschema = { version = "0.49.5", 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 }
@@ -220,9 +220,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
220
220
 
221
221
  [[package]]
222
222
  name = "fancy-regex"
223
- version = "0.18.0"
223
+ version = "0.19.0"
224
224
  source = "registry+https://github.com/rust-lang/crates.io-index"
225
- checksum = "e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277"
225
+ checksum = "476de73bddf2ef8490aa4ee8f1cf40b430bf1d56c48c22080e5186952cd580e6"
226
226
  dependencies = [
227
227
  "bit-set",
228
228
  "regex-automata",
@@ -693,9 +693,9 @@ dependencies = [
693
693
 
694
694
  [[package]]
695
695
  name = "jsonschema"
696
- version = "0.49.3"
696
+ version = "0.49.5"
697
697
  source = "registry+https://github.com/rust-lang/crates.io-index"
698
- checksum = "508004a5500f2e1f68af048f70feea2de86d35ab115d85716530860822aef397"
698
+ checksum = "8da60094fc1968bbd091e2cfa004415cb7b19e25e592376e66a64aa832bb6039"
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.3"
729
+ version = "0.49.5"
730
730
  source = "registry+https://github.com/rust-lang/crates.io-index"
731
- checksum = "f4e131231bc18676df289bd7634d4353d5b36bced191928bfa2a2dcae91e44a0"
731
+ checksum = "1575f559a96e0cd2b83afd25b868507d39b97e16af2ed7d23074c470b0259627"
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.3"
739
+ version = "0.49.5"
740
740
  source = "registry+https://github.com/rust-lang/crates.io-index"
741
- checksum = "75803a5014f912d5a8f3c8cc24531d19ea06dfadda75ddf1d15af629f7c8468c"
741
+ checksum = "4d2d8f4ec940ac30dc8e85787916ac6a9d34fcfa850b47ffe69205e837dee621"
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.3"
758
+ version = "0.49.5"
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.3"
771
+ version = "0.49.5"
772
772
  source = "registry+https://github.com/rust-lang/crates.io-index"
773
- checksum = "5a8b30cafa78358ae6cd1494a7d6410b89530e28bf567f862c869c667e900d9f"
773
+ checksum = "36539f34ef9e5da418433fbbf7294522d8f930ecf6a540ccd1ec6481c9ff9056"
774
774
  dependencies = [
775
775
  "regex-syntax",
776
776
  ]
777
777
 
778
778
  [[package]]
779
779
  name = "jsonschema-value"
780
- version = "0.49.3"
780
+ version = "0.49.5"
781
781
  source = "registry+https://github.com/rust-lang/crates.io-index"
782
- checksum = "5526bd381d230af94908d07e6835a33fd82a465e12f5f1e9c81f5c2aa23b3c21"
782
+ checksum = "8bc513dfee68c6fe29498451df95a32951ea227801b476f4a1f236433986c891"
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.3"
1135
+ version = "0.49.5"
1136
1136
  source = "registry+https://github.com/rust-lang/crates.io-index"
1137
- checksum = "7af3eb523cce0df0af3c30d624b829b2dabd233172b5bc2615fcd03ceae8f746"
1137
+ checksum = "05915176d843da9ec5c925e5e2631be9aa61b27430acfdd562e79cae8f559725"
1138
1138
  dependencies = [
1139
1139
  "ahash",
1140
1140
  "fluent-uri",
@@ -1161,9 +1161,9 @@ dependencies = [
1161
1161
 
1162
1162
  [[package]]
1163
1163
  name = "regex-automata"
1164
- version = "0.4.14"
1164
+ version = "0.4.18"
1165
1165
  source = "registry+https://github.com/rust-lang/crates.io-index"
1166
- checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
1166
+ checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
1167
1167
  dependencies = [
1168
1168
  "aho-corasick",
1169
1169
  "memchr",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "jsonschema-rb-ext"
3
- version = "0.49.3"
3
+ version = "0.49.5"
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.3", default-features = false, features = ["magnus", "arbitrary-precision", "resolve-http", "resolve-file", "tls-ring", "macros"] }
13
+ jsonschema = { version = "0.49.5", 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.3"
16
+ referencing = "0.49.5"
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.3"
4
+ VERSION = "0.49.5"
5
5
  end
data/sig/jsonschema.rbs CHANGED
@@ -32,12 +32,22 @@ module JSONSchema
32
32
  class InvalidPattern < CanonicalizationError
33
33
  end
34
34
 
35
+ class IncompatibleOperands < CanonicalizationError
36
+ end
37
+
38
+ class UnmodeledOperand < CanonicalizationError
39
+ end
40
+
35
41
  # A schema reduced to canonical form: schemas accepting the same values share one form.
36
42
  class CanonicalSchema
37
43
  def to_json_schema: () -> untyped
38
44
  def draft: () -> JSONSchema::draft
39
45
  def kind: () -> kind
40
46
  def view: () -> view
47
+ def intersect: (CanonicalSchema other) -> CanonicalSchema
48
+ def is_subset_of: (CanonicalSchema other) -> bool?
49
+ def negate: () -> CanonicalSchema?
50
+ def definition: (String uri) -> CanonicalSchema?
41
51
  def definitions: () -> Hash[String, CanonicalSchema]
42
52
  def satisfiable?: () -> bool
43
53
  def inspect: () -> String
@@ -74,9 +84,12 @@ module JSONSchema
74
84
  def min_length: () -> Integer?
75
85
  def max_length: () -> Integer?
76
86
  def patterns: () -> Array[String]
87
+ def excluded_patterns: () -> Array[String]
77
88
  def formats: () -> Array[String]
89
+ def excluded_formats: () -> Array[String]
78
90
  def content_media_types: () -> Array[String]
79
91
  def content_encodings: () -> Array[String]
92
+ def excluded: () -> Array[String]
80
93
  def inspect: () -> String
81
94
  def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
82
95
  end
@@ -88,6 +101,8 @@ module JSONSchema
88
101
  def maximum: () -> (Integer | Float)?
89
102
  def exclusive_maximum: () -> bool
90
103
  def multiple_of: () -> Array[Integer | Float]
104
+ def not_multiple_of: () -> Array[Integer | Float]
105
+ def excludes_integers: () -> bool
91
106
  def inspect: () -> String
92
107
  def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
93
108
  end
@@ -97,6 +112,7 @@ module JSONSchema
97
112
  def minimum: () -> Integer?
98
113
  def maximum: () -> Integer?
99
114
  def multiple_of: () -> Array[Integer | Float]
115
+ def not_multiple_of: () -> Array[Integer | Float]
100
116
  def inspect: () -> String
101
117
  def deconstruct_keys: (untyped keys) -> Hash[Symbol, untyped]
102
118
  end
data/src/canonical.rs CHANGED
@@ -47,6 +47,8 @@ macro_rules! canonical_error_class {
47
47
  canonical_error_class!(CANONICALIZATION_ERROR_CLASS, "CanonicalizationError");
48
48
  canonical_error_class!(INVALID_SCHEMA_TYPE_CLASS, "InvalidSchemaType");
49
49
  canonical_error_class!(INVALID_PATTERN_CLASS, "InvalidPattern");
50
+ canonical_error_class!(INCOMPATIBLE_OPERANDS_CLASS, "IncompatibleOperands");
51
+ canonical_error_class!(UNMODELED_OPERAND_CLASS, "UnmodeledOperand");
50
52
 
51
53
  fn canonicalization_error(ruby: &Ruby, error: CanonicalizationError) -> Error {
52
54
  if let CanonicalizationError::ValidationError(validation_error) = error {
@@ -60,6 +62,12 @@ fn canonicalization_error(ruby: &Ruby, error: CanonicalizationError) -> Error {
60
62
  CanonicalizationError::InvalidPattern { .. } => {
61
63
  Error::new(ruby.get_inner(&INVALID_PATTERN_CLASS), message)
62
64
  }
65
+ CanonicalizationError::IncompatibleOperands(_) => {
66
+ Error::new(ruby.get_inner(&INCOMPATIBLE_OPERANDS_CLASS), message)
67
+ }
68
+ CanonicalizationError::UnmodeledOperand => {
69
+ Error::new(ruby.get_inner(&UNMODELED_OPERAND_CLASS), message)
70
+ }
63
71
  // `ValidationError` returns above; future variants fall back to the base canonical error.
64
72
  _ => Error::new(ruby.get_inner(&CANONICALIZATION_ERROR_CLASS), message),
65
73
  }
@@ -140,9 +148,12 @@ impl RbCanonicalSchema {
140
148
  min_length: view.min_length,
141
149
  max_length: view.max_length,
142
150
  patterns: view.patterns,
151
+ excluded_patterns: view.excluded_patterns,
143
152
  formats: view.formats,
153
+ excluded_formats: view.excluded_formats,
144
154
  content_media_types: view.content_media_types,
145
155
  content_encodings: view.content_encodings,
156
+ excluded: view.excluded,
146
157
  })
147
158
  .as_value(),
148
159
  CanonicalView::Number(view) => ruby
@@ -152,6 +163,8 @@ impl RbCanonicalSchema {
152
163
  maximum: view.maximum,
153
164
  exclusive_maximum: view.exclusive_maximum,
154
165
  multiple_of: view.multiple_of,
166
+ not_multiple_of: view.not_multiple_of,
167
+ excludes_integers: view.excludes_integers,
155
168
  })
156
169
  .as_value(),
157
170
  CanonicalView::Integer(view) => ruby
@@ -159,6 +172,7 @@ impl RbCanonicalSchema {
159
172
  minimum: view.minimum,
160
173
  maximum: view.maximum,
161
174
  multiple_of: view.multiple_of,
175
+ not_multiple_of: view.not_multiple_of,
162
176
  })
163
177
  .as_value(),
164
178
  CanonicalView::Array(view) => ruby
@@ -191,6 +205,36 @@ impl RbCanonicalSchema {
191
205
  }
192
206
  }
193
207
 
208
+ fn intersect(ruby: &Ruby, rb_self: &Self, other: &Self) -> Result<Value, Error> {
209
+ rb_self
210
+ .inner
211
+ .intersect(&other.inner)
212
+ .map(|inner| ruby.obj_wrap(RbCanonicalSchema { inner }).as_value())
213
+ .map_err(|error| canonicalization_error(ruby, error))
214
+ }
215
+
216
+ fn is_subset_of(ruby: &Ruby, rb_self: &Self, other: &Self) -> Result<Option<bool>, Error> {
217
+ rb_self
218
+ .inner
219
+ .is_subset_of(&other.inner)
220
+ .map_err(|error| canonicalization_error(ruby, error))
221
+ }
222
+
223
+ fn negate(ruby: &Ruby, rb_self: &Self) -> Option<Value> {
224
+ rb_self
225
+ .inner
226
+ .negate()
227
+ .map(|inner| ruby.obj_wrap(RbCanonicalSchema { inner }).as_value())
228
+ }
229
+
230
+ #[allow(clippy::needless_pass_by_value)]
231
+ fn definition(ruby: &Ruby, rb_self: &Self, uri: String) -> Option<Value> {
232
+ rb_self
233
+ .inner
234
+ .definition(&uri)
235
+ .map(|inner| ruby.obj_wrap(RbCanonicalSchema { inner }).as_value())
236
+ }
237
+
194
238
  fn definitions(ruby: &Ruby, rb_self: &Self) -> Result<RHash, Error> {
195
239
  let hash = ruby.hash_new();
196
240
  for (uri, target) in rb_self.inner.definitions() {
@@ -354,17 +398,19 @@ fn strings_to_ruby(ruby: &Ruby, values: &[String]) -> Result<Value, Error> {
354
398
  Ok(array.as_value())
355
399
  }
356
400
 
357
- /// A string value within a length window, matching every pattern, format, media type, and
358
- /// encoding.
401
+ /// A string value within a length window, matching every required facet and no barred one.
359
402
  #[derive(magnus::TypedData)]
360
403
  #[magnus(class = "JSONSchema::Canonical::StringView", free_immediately)]
361
404
  pub struct StringView {
362
405
  min_length: Option<serde_json::Number>,
363
406
  max_length: Option<serde_json::Number>,
364
407
  patterns: Vec<String>,
408
+ excluded_patterns: Vec<String>,
365
409
  formats: Vec<String>,
410
+ excluded_formats: Vec<String>,
366
411
  content_media_types: Vec<String>,
367
412
  content_encodings: Vec<String>,
413
+ excluded: Vec<String>,
368
414
  }
369
415
 
370
416
  impl DataTypeFunctions for StringView {}
@@ -382,10 +428,18 @@ impl StringView {
382
428
  strings_to_ruby(ruby, &rb_self.patterns)
383
429
  }
384
430
 
431
+ fn excluded_patterns(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
432
+ strings_to_ruby(ruby, &rb_self.excluded_patterns)
433
+ }
434
+
385
435
  fn formats(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
386
436
  strings_to_ruby(ruby, &rb_self.formats)
387
437
  }
388
438
 
439
+ fn excluded_formats(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
440
+ strings_to_ruby(ruby, &rb_self.excluded_formats)
441
+ }
442
+
389
443
  fn content_media_types(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
390
444
  strings_to_ruby(ruby, &rb_self.content_media_types)
391
445
  }
@@ -394,15 +448,22 @@ impl StringView {
394
448
  strings_to_ruby(ruby, &rb_self.content_encodings)
395
449
  }
396
450
 
451
+ fn excluded(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
452
+ strings_to_ruby(ruby, &rb_self.excluded)
453
+ }
454
+
397
455
  fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
398
456
  Ok(format!(
399
- "#<JSONSchema::Canonical::StringView min_length={} max_length={} patterns={} formats={} content_media_types={} content_encodings={}>",
457
+ "#<JSONSchema::Canonical::StringView min_length={} max_length={} patterns={} excluded_patterns={} formats={} excluded_formats={} content_media_types={} content_encodings={} excluded={}>",
400
458
  Self::min_length(ruby, rb_self)?.inspect(),
401
459
  Self::max_length(ruby, rb_self)?.inspect(),
402
460
  Self::patterns(ruby, rb_self)?.inspect(),
461
+ Self::excluded_patterns(ruby, rb_self)?.inspect(),
403
462
  Self::formats(ruby, rb_self)?.inspect(),
463
+ Self::excluded_formats(ruby, rb_self)?.inspect(),
404
464
  Self::content_media_types(ruby, rb_self)?.inspect(),
405
- Self::content_encodings(ruby, rb_self)?.inspect()
465
+ Self::content_encodings(ruby, rb_self)?.inspect(),
466
+ Self::excluded(ruby, rb_self)?.inspect()
406
467
  ))
407
468
  }
408
469
 
@@ -411,7 +472,15 @@ impl StringView {
411
472
  hash.aset(ruby.sym_new("min_length"), Self::min_length(ruby, rb_self)?)?;
412
473
  hash.aset(ruby.sym_new("max_length"), Self::max_length(ruby, rb_self)?)?;
413
474
  hash.aset(ruby.sym_new("patterns"), Self::patterns(ruby, rb_self)?)?;
475
+ hash.aset(
476
+ ruby.sym_new("excluded_patterns"),
477
+ Self::excluded_patterns(ruby, rb_self)?,
478
+ )?;
414
479
  hash.aset(ruby.sym_new("formats"), Self::formats(ruby, rb_self)?)?;
480
+ hash.aset(
481
+ ruby.sym_new("excluded_formats"),
482
+ Self::excluded_formats(ruby, rb_self)?,
483
+ )?;
415
484
  hash.aset(
416
485
  ruby.sym_new("content_media_types"),
417
486
  Self::content_media_types(ruby, rb_self)?,
@@ -420,6 +489,7 @@ impl StringView {
420
489
  ruby.sym_new("content_encodings"),
421
490
  Self::content_encodings(ruby, rb_self)?,
422
491
  )?;
492
+ hash.aset(ruby.sym_new("excluded"), Self::excluded(ruby, rb_self)?)?;
423
493
  Ok(hash)
424
494
  }
425
495
  }
@@ -433,6 +503,8 @@ pub struct NumberView {
433
503
  maximum: Option<serde_json::Number>,
434
504
  exclusive_maximum: bool,
435
505
  multiple_of: Vec<serde_json::Number>,
506
+ not_multiple_of: Vec<serde_json::Number>,
507
+ excludes_integers: bool,
436
508
  }
437
509
 
438
510
  impl DataTypeFunctions for NumberView {}
@@ -458,14 +530,24 @@ impl NumberView {
458
530
  divisors_to_ruby(ruby, &rb_self.multiple_of)
459
531
  }
460
532
 
533
+ fn not_multiple_of(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
534
+ divisors_to_ruby(ruby, &rb_self.not_multiple_of)
535
+ }
536
+
537
+ fn excludes_integers(ruby: &Ruby, rb_self: &Self) -> Value {
538
+ ruby.into_value(rb_self.excludes_integers)
539
+ }
540
+
461
541
  fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
462
542
  Ok(format!(
463
- "#<JSONSchema::Canonical::NumberView minimum={} exclusive_minimum={} maximum={} exclusive_maximum={} multiple_of={}>",
543
+ "#<JSONSchema::Canonical::NumberView minimum={} exclusive_minimum={} maximum={} exclusive_maximum={} multiple_of={} not_multiple_of={} excludes_integers={}>",
464
544
  Self::minimum(ruby, rb_self)?.inspect(),
465
545
  Self::exclusive_minimum(ruby, rb_self).inspect(),
466
546
  Self::maximum(ruby, rb_self)?.inspect(),
467
547
  Self::exclusive_maximum(ruby, rb_self).inspect(),
468
- Self::multiple_of(ruby, rb_self)?.inspect()
548
+ Self::multiple_of(ruby, rb_self)?.inspect(),
549
+ Self::not_multiple_of(ruby, rb_self)?.inspect(),
550
+ Self::excludes_integers(ruby, rb_self).inspect()
469
551
  ))
470
552
  }
471
553
 
@@ -485,6 +567,14 @@ impl NumberView {
485
567
  ruby.sym_new("multiple_of"),
486
568
  Self::multiple_of(ruby, rb_self)?,
487
569
  )?;
570
+ hash.aset(
571
+ ruby.sym_new("not_multiple_of"),
572
+ Self::not_multiple_of(ruby, rb_self)?,
573
+ )?;
574
+ hash.aset(
575
+ ruby.sym_new("excludes_integers"),
576
+ Self::excludes_integers(ruby, rb_self),
577
+ )?;
488
578
  Ok(hash)
489
579
  }
490
580
  }
@@ -496,6 +586,7 @@ pub struct IntegerView {
496
586
  minimum: Option<serde_json::Number>,
497
587
  maximum: Option<serde_json::Number>,
498
588
  multiple_of: Vec<serde_json::Number>,
589
+ not_multiple_of: Vec<serde_json::Number>,
499
590
  }
500
591
 
501
592
  impl DataTypeFunctions for IntegerView {}
@@ -513,12 +604,17 @@ impl IntegerView {
513
604
  divisors_to_ruby(ruby, &rb_self.multiple_of)
514
605
  }
515
606
 
607
+ fn not_multiple_of(ruby: &Ruby, rb_self: &Self) -> Result<Value, Error> {
608
+ divisors_to_ruby(ruby, &rb_self.not_multiple_of)
609
+ }
610
+
516
611
  fn inspect(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
517
612
  Ok(format!(
518
- "#<JSONSchema::Canonical::IntegerView minimum={} maximum={} multiple_of={}>",
613
+ "#<JSONSchema::Canonical::IntegerView minimum={} maximum={} multiple_of={} not_multiple_of={}>",
519
614
  Self::minimum(ruby, rb_self)?.inspect(),
520
615
  Self::maximum(ruby, rb_self)?.inspect(),
521
- Self::multiple_of(ruby, rb_self)?.inspect()
616
+ Self::multiple_of(ruby, rb_self)?.inspect(),
617
+ Self::not_multiple_of(ruby, rb_self)?.inspect()
522
618
  ))
523
619
  }
524
620
 
@@ -530,6 +626,10 @@ impl IntegerView {
530
626
  ruby.sym_new("multiple_of"),
531
627
  Self::multiple_of(ruby, rb_self)?,
532
628
  )?;
629
+ hash.aset(
630
+ ruby.sym_new("not_multiple_of"),
631
+ Self::not_multiple_of(ruby, rb_self)?,
632
+ )?;
533
633
  Ok(hash)
534
634
  }
535
635
  }
@@ -1083,6 +1183,8 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
1083
1183
  canonical_module.define_error("CanonicalizationError", ruby.exception_standard_error())?;
1084
1184
  canonical_module.define_error("InvalidSchemaType", base_error)?;
1085
1185
  canonical_module.define_error("InvalidPattern", base_error)?;
1186
+ canonical_module.define_error("IncompatibleOperands", base_error)?;
1187
+ canonical_module.define_error("UnmodeledOperand", base_error)?;
1086
1188
 
1087
1189
  let canonical_schema = canonical_module.define_class("CanonicalSchema", ruby.class_object())?;
1088
1190
  canonical_schema.define_method(
@@ -1102,6 +1204,10 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
1102
1204
  method!(<RbCanonicalSchema as typed_data::Hash>::hash, 0),
1103
1205
  )?;
1104
1206
  canonical_schema.define_method("view", method!(RbCanonicalSchema::view, 0))?;
1207
+ canonical_schema.define_method("intersect", method!(RbCanonicalSchema::intersect, 1))?;
1208
+ canonical_schema.define_method("is_subset_of", method!(RbCanonicalSchema::is_subset_of, 1))?;
1209
+ canonical_schema.define_method("negate", method!(RbCanonicalSchema::negate, 0))?;
1210
+ canonical_schema.define_method("definition", method!(RbCanonicalSchema::definition, 1))?;
1105
1211
  canonical_schema.define_method("definitions", method!(RbCanonicalSchema::definitions, 0))?;
1106
1212
  canonical_schema.define_method("satisfiable?", method!(RbCanonicalSchema::satisfiable, 0))?;
1107
1213
 
@@ -1141,7 +1247,12 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
1141
1247
  string_view.define_method("min_length", method!(StringView::min_length, 0))?;
1142
1248
  string_view.define_method("max_length", method!(StringView::max_length, 0))?;
1143
1249
  string_view.define_method("patterns", method!(StringView::patterns, 0))?;
1250
+ string_view.define_method(
1251
+ "excluded_patterns",
1252
+ method!(StringView::excluded_patterns, 0),
1253
+ )?;
1144
1254
  string_view.define_method("formats", method!(StringView::formats, 0))?;
1255
+ string_view.define_method("excluded_formats", method!(StringView::excluded_formats, 0))?;
1145
1256
  string_view.define_method(
1146
1257
  "content_media_types",
1147
1258
  method!(StringView::content_media_types, 0),
@@ -1150,6 +1261,7 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
1150
1261
  "content_encodings",
1151
1262
  method!(StringView::content_encodings, 0),
1152
1263
  )?;
1264
+ string_view.define_method("excluded", method!(StringView::excluded, 0))?;
1153
1265
  string_view.define_method("inspect", method!(StringView::inspect, 0))?;
1154
1266
  string_view.define_method("deconstruct_keys", method!(StringView::deconstruct_keys, 1))?;
1155
1267
 
@@ -1165,6 +1277,11 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
1165
1277
  method!(NumberView::exclusive_maximum, 0),
1166
1278
  )?;
1167
1279
  number_view.define_method("multiple_of", method!(NumberView::multiple_of, 0))?;
1280
+ number_view.define_method("not_multiple_of", method!(NumberView::not_multiple_of, 0))?;
1281
+ number_view.define_method(
1282
+ "excludes_integers",
1283
+ method!(NumberView::excludes_integers, 0),
1284
+ )?;
1168
1285
  number_view.define_method("inspect", method!(NumberView::inspect, 0))?;
1169
1286
  number_view.define_method("deconstruct_keys", method!(NumberView::deconstruct_keys, 1))?;
1170
1287
 
@@ -1172,6 +1289,7 @@ pub(crate) fn init_canonical(ruby: &Ruby, module: &RModule) -> Result<(), Error>
1172
1289
  integer_view.define_method("minimum", method!(IntegerView::minimum, 0))?;
1173
1290
  integer_view.define_method("maximum", method!(IntegerView::maximum, 0))?;
1174
1291
  integer_view.define_method("multiple_of", method!(IntegerView::multiple_of, 0))?;
1292
+ integer_view.define_method("not_multiple_of", method!(IntegerView::not_multiple_of, 0))?;
1175
1293
  integer_view.define_method("inspect", method!(IntegerView::inspect, 0))?;
1176
1294
  integer_view.define_method(
1177
1295
  "deconstruct_keys",
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.3
4
+ version: 0.49.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dygalo