jsonschema_rs 0.42.1 → 0.42.2
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/CHANGELOG.md +17 -1
- data/Cargo.toml +2 -2
- data/README.md +14 -3
- data/ext/jsonschema/Cargo.lock +5 -5
- data/ext/jsonschema/Cargo.toml +3 -3
- data/lib/jsonschema/version.rb +1 -1
- data/src/lib.rs +17 -0
- data/src/options.rs +8 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5e7d5176039d2b2ed57477cf0df4ae678c7621a1bdd58928f446c248c891faaa
|
|
4
|
+
data.tar.gz: '09bb34e4ab1ade80c168cd1e0a5261f9a84915f4f044a1a7d3172b0c8e381b7a'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d0b1526111cdbe307b01244486e827f93cfa390f79daf41e1ccfb920ec1ab9050e6474d49282627d303e5e28af8da629e7c35153a2321e6ae22b8e323b04b2b1
|
|
7
|
+
data.tar.gz: ebc8c709a96970c566bb26ee36a9373a13c91b7ebdb3634c43c0b33250dc7df8a227836e727d86497c190d41a853d911e03bd3cd625a75050c04b970253da759
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.42.2] - 2026-02-26
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Custom keyword validation exceptions are now chained to the resulting `ValidationError` via `cause`, preserving the original exception class and message.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- SWAR digit parser accepted bytes `:`–`?` (0x3A–0x3F) as valid digits during `date`, `time`, and `date-time` format validation, potentially allowing malformed values to pass.
|
|
14
|
+
|
|
15
|
+
### Performance
|
|
16
|
+
|
|
17
|
+
- Extend `pattern` prefix optimization to handle escaped slashes (`^\/`) and exact-match patterns (`^\$ref$`).
|
|
18
|
+
- Specialize `enum` for cases when all variants are strings.
|
|
19
|
+
|
|
5
20
|
## [0.42.1] - 2026-02-17
|
|
6
21
|
|
|
7
22
|
### Performance
|
|
@@ -13,5 +28,6 @@
|
|
|
13
28
|
|
|
14
29
|
- Initial public release
|
|
15
30
|
|
|
16
|
-
[Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.42.
|
|
31
|
+
[Unreleased]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.42.2...HEAD
|
|
32
|
+
[0.42.2]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.42.1...ruby-v0.42.2
|
|
17
33
|
[0.42.1]: https://github.com/Stranger6667/jsonschema/compare/ruby-v0.42.0...ruby-v0.42.1
|
data/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "jsonschema-rb"
|
|
3
|
-
version = "0.42.
|
|
3
|
+
version = "0.42.2"
|
|
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.42.
|
|
16
|
+
jsonschema = { version = "0.42.2", default-features = false, features = ["arbitrary-precision", "resolve-http", "resolve-file", "tls-ring"] }
|
|
17
17
|
magnus = { version = "0.8", features = ["rb-sys"] }
|
|
18
18
|
rb-sys = "0.9"
|
|
19
19
|
serde = { workspace = true }
|
data/README.md
CHANGED
|
@@ -147,6 +147,17 @@ Each custom keyword class must implement:
|
|
|
147
147
|
- `initialize(parent_schema, value, schema_path)` - called during schema compilation
|
|
148
148
|
- `validate(instance)` - raise on failure, return normally on success
|
|
149
149
|
|
|
150
|
+
When `validate` raises, the original exception is preserved as the `cause` of the `ValidationError`, so callers can inspect it:
|
|
151
|
+
|
|
152
|
+
```ruby
|
|
153
|
+
begin
|
|
154
|
+
validator.validate!(3)
|
|
155
|
+
rescue JSONSchema::ValidationError => e
|
|
156
|
+
puts e.cause.class # => RuntimeError
|
|
157
|
+
puts e.cause.message # => "3 is not even"
|
|
158
|
+
end
|
|
159
|
+
```
|
|
160
|
+
|
|
150
161
|
### Structured evaluation output
|
|
151
162
|
|
|
152
163
|
When you need more than a boolean result, use the `evaluate` API to access the [JSON Schema Output v1](https://json-schema.org/draft/2020-12/json-schema-core#name-output-formatting) formats:
|
|
@@ -505,9 +516,9 @@ Valid draft symbols: `:draft4`, `:draft6`, `:draft7`, `:draft201909`, `:draft202
|
|
|
505
516
|
|
|
506
517
|
`jsonschema` is designed for high performance, outperforming other Ruby JSON Schema validators in most scenarios:
|
|
507
518
|
|
|
508
|
-
- **
|
|
509
|
-
- **
|
|
510
|
-
- **7-
|
|
519
|
+
- **28-148x** faster than `json_schemer` for complex schemas and large instances
|
|
520
|
+
- **200-567x** faster than `json-schema` where supported
|
|
521
|
+
- **7-130x** faster than `rj_schema` (RapidJSON/C++)
|
|
511
522
|
|
|
512
523
|
For detailed benchmarks, see our [full performance comparison](https://github.com/Stranger6667/jsonschema/blob/master/crates/jsonschema-rb/BENCHMARKS.md).
|
|
513
524
|
|
data/ext/jsonschema/Cargo.lock
CHANGED
|
@@ -667,9 +667,9 @@ dependencies = [
|
|
|
667
667
|
|
|
668
668
|
[[package]]
|
|
669
669
|
name = "jsonschema"
|
|
670
|
-
version = "0.42.
|
|
670
|
+
version = "0.42.2"
|
|
671
671
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
672
|
-
checksum = "
|
|
672
|
+
checksum = "a44c9bb95f6ac9270bf4fd38d71c2f8704b9fe0323a293af7a5284cbd60a39b2"
|
|
673
673
|
dependencies = [
|
|
674
674
|
"ahash",
|
|
675
675
|
"bytecount",
|
|
@@ -697,7 +697,7 @@ dependencies = [
|
|
|
697
697
|
|
|
698
698
|
[[package]]
|
|
699
699
|
name = "jsonschema-rb-ext"
|
|
700
|
-
version = "0.42.
|
|
700
|
+
version = "0.42.2"
|
|
701
701
|
dependencies = [
|
|
702
702
|
"jsonschema",
|
|
703
703
|
"magnus",
|
|
@@ -1044,9 +1044,9 @@ dependencies = [
|
|
|
1044
1044
|
|
|
1045
1045
|
[[package]]
|
|
1046
1046
|
name = "referencing"
|
|
1047
|
-
version = "0.42.
|
|
1047
|
+
version = "0.42.2"
|
|
1048
1048
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1049
|
-
checksum = "
|
|
1049
|
+
checksum = "97d4124f489451bb67c59d67fa16f3ae9b5690b290406a7538e38458632666df"
|
|
1050
1050
|
dependencies = [
|
|
1051
1051
|
"ahash",
|
|
1052
1052
|
"fluent-uri",
|
data/ext/jsonschema/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "jsonschema-rb-ext"
|
|
3
|
-
version = "0.42.
|
|
3
|
+
version = "0.42.2"
|
|
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.42.
|
|
13
|
+
jsonschema = { version = "0.42.2", default-features = false, features = ["arbitrary-precision", "resolve-http", "resolve-file", "tls-ring"] }
|
|
14
14
|
magnus = { version = "0.8", features = ["rb-sys"] }
|
|
15
15
|
rb-sys = "0.9"
|
|
16
|
-
referencing = "0.42.
|
|
16
|
+
referencing = "0.42.2"
|
|
17
17
|
serde = { version = "1", features = ["derive"] }
|
|
18
18
|
serde_json = { version = "1", features = ["arbitrary_precision"] }
|
|
19
19
|
|
data/lib/jsonschema/version.rb
CHANGED
data/src/lib.rs
CHANGED
|
@@ -15,6 +15,7 @@ mod static_id;
|
|
|
15
15
|
|
|
16
16
|
use jsonschema::{paths::LocationSegment, ValidationOptions};
|
|
17
17
|
use magnus::{
|
|
18
|
+
error::ErrorType,
|
|
18
19
|
function,
|
|
19
20
|
gc::{register_address, register_mark_object, unregister_address},
|
|
20
21
|
method,
|
|
@@ -58,6 +59,7 @@ define_rb_intern!(static ID_AT_SCHEMA_PATH_POINTER: "@schema_path_pointer");
|
|
|
58
59
|
define_rb_intern!(static ID_AT_EVALUATION_PATH_POINTER: "@evaluation_path_pointer");
|
|
59
60
|
define_rb_intern!(static ID_AT_KIND: "@kind");
|
|
60
61
|
define_rb_intern!(static ID_AT_INSTANCE: "@instance");
|
|
62
|
+
define_rb_intern!(static ID_CAUSE: "cause");
|
|
61
63
|
|
|
62
64
|
define_rb_intern!(static ID_SYM_MESSAGE: "message");
|
|
63
65
|
define_rb_intern!(static ID_SYM_VERBOSE_MESSAGE: "verbose_message");
|
|
@@ -187,6 +189,9 @@ fn build_parsed_options(
|
|
|
187
189
|
|
|
188
190
|
thread_local! {
|
|
189
191
|
static LAST_CALLBACK_ERROR: RefCell<Option<Error>> = const { RefCell::new(None) };
|
|
192
|
+
// Stores the original Ruby exception from a custom keyword's validate() call so it can be
|
|
193
|
+
// set as the `cause` on the resulting ValidationError.
|
|
194
|
+
pub(crate) static CUSTOM_KEYWORD_CAUSE: RefCell<Option<Error>> = const { RefCell::new(None) };
|
|
190
195
|
/// When `true`, the custom panic hook suppresses output (inside `catch_unwind` blocks).
|
|
191
196
|
static SUPPRESS_PANIC_OUTPUT: RefCell<bool> = const { RefCell::new(false) };
|
|
192
197
|
}
|
|
@@ -353,6 +358,10 @@ fn into_ruby_error(
|
|
|
353
358
|
message: &str,
|
|
354
359
|
mask: Option<&str>,
|
|
355
360
|
) -> Result<Value, Error> {
|
|
361
|
+
let is_custom = matches!(
|
|
362
|
+
error.kind(),
|
|
363
|
+
jsonschema::error::ValidationErrorKind::Custom { .. }
|
|
364
|
+
);
|
|
356
365
|
let rb_message = ruby.into_value(message);
|
|
357
366
|
let verbose_message = build_verbose_message(
|
|
358
367
|
message.to_owned(),
|
|
@@ -406,6 +415,14 @@ fn into_ruby_error(
|
|
|
406
415
|
exc.ivar_set(*ID_AT_KIND, ruby.into_value(kind_obj))?;
|
|
407
416
|
exc.ivar_set(*ID_AT_INSTANCE, rb_instance)?;
|
|
408
417
|
|
|
418
|
+
if is_custom {
|
|
419
|
+
if let Some(cause) = CUSTOM_KEYWORD_CAUSE.with(|cell| cell.borrow_mut().take()) {
|
|
420
|
+
if let ErrorType::Exception(cause_exc) = cause.error_type() {
|
|
421
|
+
exc.ivar_set(*ID_CAUSE, cause_exc.as_value())?;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
409
426
|
Ok(exc.as_value())
|
|
410
427
|
}
|
|
411
428
|
|
data/src/options.rs
CHANGED
|
@@ -20,7 +20,7 @@ use crate::{
|
|
|
20
20
|
retriever::{make_retriever, RubyRetriever},
|
|
21
21
|
ser::{map_to_ruby, value_to_ruby},
|
|
22
22
|
static_id::{define_rb_intern, StaticId},
|
|
23
|
-
LAST_CALLBACK_ERROR,
|
|
23
|
+
CUSTOM_KEYWORD_CAUSE, LAST_CALLBACK_ERROR,
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
// Base kwarg names
|
|
@@ -384,7 +384,13 @@ impl jsonschema::Keyword for RubyKeyword {
|
|
|
384
384
|
let result: Result<Value, _> = keyword.funcall("validate", (rb_instance,));
|
|
385
385
|
match result {
|
|
386
386
|
Ok(_) => Ok(()),
|
|
387
|
-
Err(e) =>
|
|
387
|
+
Err(e) => {
|
|
388
|
+
let msg = e.to_string();
|
|
389
|
+
CUSTOM_KEYWORD_CAUSE.with(|cell| {
|
|
390
|
+
*cell.borrow_mut() = Some(e);
|
|
391
|
+
});
|
|
392
|
+
Err(jsonschema::ValidationError::custom(msg))
|
|
393
|
+
}
|
|
388
394
|
}
|
|
389
395
|
}
|
|
390
396
|
|