jsonschema_rs 0.48.5 → 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 +4 -4
- data/CHANGELOG.md +22 -1
- data/Cargo.toml +2 -2
- data/ext/jsonschema/Cargo.lock +15 -13
- data/ext/jsonschema/Cargo.toml +3 -3
- data/lib/jsonschema/version.rb +1 -1
- data/sig/jsonschema.rbs +53 -4
- data/src/canonical.rs +492 -14
- data/src/lib.rs +110 -295
- data/src/options.rs +24 -21
- data/src/validator_map.rs +1 -4
- metadata +1 -1
data/src/options.rs
CHANGED
|
@@ -15,6 +15,8 @@ use magnus::{
|
|
|
15
15
|
Error, Exception, RArray, RHash, RModule, Ruby, TryConvert, Value,
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
use jsonschema::json::{magnus_invalidate_members_cache, Magnus, RbNode};
|
|
19
|
+
|
|
18
20
|
use crate::{
|
|
19
21
|
registry::Registry,
|
|
20
22
|
retriever::{make_retriever, RubyRetriever},
|
|
@@ -58,7 +60,7 @@ define_rb_intern!(static SYM_VALIDATE: "validate");
|
|
|
58
60
|
|
|
59
61
|
pub struct ParsedOptions<'i> {
|
|
60
62
|
pub mask: Option<String>,
|
|
61
|
-
pub options: jsonschema::ValidationOptions<'i>,
|
|
63
|
+
pub options: jsonschema::ValidationOptions<'i, Arc<dyn jsonschema::Retrieve>, Magnus>,
|
|
62
64
|
pub registry: Option<&'i jsonschema::Registry<'static>>,
|
|
63
65
|
pub retriever: Option<RubyRetriever>,
|
|
64
66
|
// Runtime callbacks invoked during `validator.*` calls (formats / custom keywords).
|
|
@@ -349,6 +351,7 @@ impl RubyFormatChecker {
|
|
|
349
351
|
let ruby = Ruby::get().expect("Ruby VM should be initialized");
|
|
350
352
|
let proc = ruby.get_inner(self.proc);
|
|
351
353
|
let result: Result<bool, _> = proc.call((value,));
|
|
354
|
+
magnus_invalidate_members_cache();
|
|
352
355
|
match result {
|
|
353
356
|
Ok(v) => v,
|
|
354
357
|
Err(e) => {
|
|
@@ -371,18 +374,21 @@ struct RubyKeyword {
|
|
|
371
374
|
instance: Opaque<Value>,
|
|
372
375
|
}
|
|
373
376
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
377
|
+
fn node_to_ruby(node: RbNode<'_>) -> Value {
|
|
378
|
+
#[allow(unsafe_code)]
|
|
379
|
+
unsafe {
|
|
380
|
+
magnus::rb_sys::FromRawValue::from_raw(node.raw())
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
impl<'i> jsonschema::Keyword<'i, Magnus> for RubyKeyword {
|
|
385
|
+
fn validate(&self, instance: RbNode<'i>) -> Result<(), jsonschema::ValidationError<'i>> {
|
|
379
386
|
let ruby = Ruby::get().expect("Ruby VM should be initialized");
|
|
380
|
-
let rb_instance =
|
|
381
|
-
jsonschema::ValidationError::custom(format!("Failed to convert instance to Ruby: {e}"))
|
|
382
|
-
})?;
|
|
387
|
+
let rb_instance = node_to_ruby(instance);
|
|
383
388
|
|
|
384
389
|
let keyword = ruby.get_inner(self.instance);
|
|
385
390
|
let result: Result<Value, _> = keyword.funcall("validate", (rb_instance,));
|
|
391
|
+
magnus_invalidate_members_cache();
|
|
386
392
|
match result {
|
|
387
393
|
Ok(_) => Ok(()),
|
|
388
394
|
Err(e) => {
|
|
@@ -395,19 +401,18 @@ impl jsonschema::Keyword for RubyKeyword {
|
|
|
395
401
|
}
|
|
396
402
|
}
|
|
397
403
|
|
|
398
|
-
fn is_valid(&self, instance:
|
|
404
|
+
fn is_valid(&self, instance: RbNode<'i>) -> bool {
|
|
399
405
|
let ruby = Ruby::get().expect("Ruby VM should be initialized");
|
|
400
|
-
let
|
|
401
|
-
return false;
|
|
402
|
-
};
|
|
406
|
+
let rb_instance = node_to_ruby(instance);
|
|
403
407
|
let inst = ruby.get_inner(self.instance);
|
|
404
408
|
let result: Result<Value, _> = inst.funcall("validate", (rb_instance,));
|
|
409
|
+
magnus_invalidate_members_cache();
|
|
405
410
|
result.is_ok()
|
|
406
411
|
}
|
|
407
412
|
|
|
408
|
-
fn iter_errors
|
|
413
|
+
fn iter_errors(
|
|
409
414
|
&self,
|
|
410
|
-
instance:
|
|
415
|
+
instance: RbNode<'i>,
|
|
411
416
|
) -> Box<dyn Iterator<Item = jsonschema::ValidationError<'i>> + 'i> {
|
|
412
417
|
let ruby = Ruby::get().expect("Ruby VM should be initialized");
|
|
413
418
|
let keyword = ruby.get_inner(self.instance);
|
|
@@ -415,13 +420,11 @@ impl jsonschema::Keyword for RubyKeyword {
|
|
|
415
420
|
if !keyword.respond_to("iter_errors", false).unwrap_or(false) {
|
|
416
421
|
return Box::new(self.validate(instance).err().into_iter());
|
|
417
422
|
}
|
|
418
|
-
let rb_instance =
|
|
419
|
-
Ok(rb_instance) => rb_instance,
|
|
420
|
-
Err(error) => return Box::new(std::iter::once(custom_error_from_ruby(error))),
|
|
421
|
-
};
|
|
423
|
+
let rb_instance = node_to_ruby(instance);
|
|
422
424
|
let array = keyword
|
|
423
425
|
.funcall::<_, _, Value>("iter_errors", (rb_instance,))
|
|
424
426
|
.and_then(|result| result.funcall::<_, _, RArray>("to_a", ()));
|
|
427
|
+
magnus_invalidate_members_cache();
|
|
425
428
|
let array = match array {
|
|
426
429
|
Ok(array) => array,
|
|
427
430
|
Err(error) => return Box::new(std::iter::once(custom_error_from_ruby(error))),
|
|
@@ -483,7 +486,7 @@ pub fn make_options_from_kwargs(
|
|
|
483
486
|
email_options_val: Option<Value>,
|
|
484
487
|
http_options_val: Option<Value>,
|
|
485
488
|
) -> Result<ParsedOptions<'_>, Error> {
|
|
486
|
-
let mut opts = jsonschema::
|
|
489
|
+
let mut opts = jsonschema::options_for::<Magnus>();
|
|
487
490
|
let mut registry = None;
|
|
488
491
|
let mut retriever = None;
|
|
489
492
|
let retriever_was_provided = retriever_val.is_some();
|
|
@@ -726,7 +729,7 @@ pub fn make_options_from_kwargs(
|
|
|
726
729
|
Ok(Box::new(RubyKeyword {
|
|
727
730
|
instance: opaque_inst,
|
|
728
731
|
})
|
|
729
|
-
as Box<dyn jsonschema::Keyword
|
|
732
|
+
as Box<dyn for<'i> jsonschema::Keyword<'i, Magnus>>)
|
|
730
733
|
}
|
|
731
734
|
Err(e) => Err(jsonschema::ValidationError::custom(format!(
|
|
732
735
|
"Failed to instantiate keyword class '{name_err}': {e}"
|
data/src/validator_map.rs
CHANGED
|
@@ -10,8 +10,7 @@ use crate::{
|
|
|
10
10
|
#[derive(TypedData)]
|
|
11
11
|
#[magnus(class = "JSONSchema::ValidatorMap", free_immediately, size, mark)]
|
|
12
12
|
pub struct ValidatorMap {
|
|
13
|
-
pub(crate) inner: jsonschema::ValidatorMap
|
|
14
|
-
pub(crate) has_ruby_callbacks: bool,
|
|
13
|
+
pub(crate) inner: jsonschema::ValidatorMap<jsonschema::json::Magnus>,
|
|
15
14
|
pub(crate) callback_roots: CallbackRoots,
|
|
16
15
|
pub(crate) compilation_roots: CompilationRootsRef,
|
|
17
16
|
pub(crate) mask: Option<String>,
|
|
@@ -38,7 +37,6 @@ impl ValidatorMap {
|
|
|
38
37
|
Validator::from_jsonschema_with_roots(
|
|
39
38
|
v.clone(),
|
|
40
39
|
self.mask.clone(),
|
|
41
|
-
self.has_ruby_callbacks,
|
|
42
40
|
self.callback_roots.clone(),
|
|
43
41
|
self.compilation_roots.clone(),
|
|
44
42
|
)
|
|
@@ -52,7 +50,6 @@ impl ValidatorMap {
|
|
|
52
50
|
Some(v) => Ok(Validator::from_jsonschema_with_roots(
|
|
53
51
|
v.clone(),
|
|
54
52
|
rb_self.mask.clone(),
|
|
55
|
-
rb_self.has_ruby_callbacks,
|
|
56
53
|
rb_self.callback_roots.clone(),
|
|
57
54
|
rb_self.compilation_roots.clone(),
|
|
58
55
|
)),
|