@@ -27,12 +27,12 @@ use super::scoped_visit::{
27
27
/// with advanced subschema validation, such as `oneOf` or `allOf`, as `unevaluatedProperties`
28
28
/// cannot simply be applied to any and all schemas indiscriminately.
29
29
#[ derive( Debug , Default ) ]
30
- pub struct DisallowedUnevaluatedPropertiesVisitor {
30
+ pub struct DisallowUnevaluatedPropertiesVisitor {
31
31
scope_stack : SchemaScopeStack ,
32
32
eligible_to_flatten : HashMap < String , HashSet < SchemaReference > > ,
33
33
}
34
34
35
- impl DisallowedUnevaluatedPropertiesVisitor {
35
+ impl DisallowUnevaluatedPropertiesVisitor {
36
36
pub fn from_settings ( _: & SchemaSettings ) -> Self {
37
37
Self {
38
38
scope_stack : SchemaScopeStack :: default ( ) ,
@@ -41,7 +41,7 @@ impl DisallowedUnevaluatedPropertiesVisitor {
41
41
}
42
42
}
43
43
44
- impl Visitor for DisallowedUnevaluatedPropertiesVisitor {
44
+ impl Visitor for DisallowUnevaluatedPropertiesVisitor {
45
45
fn visit_root_schema ( & mut self , root : & mut RootSchema ) {
46
46
let eligible_to_flatten = build_closed_schema_flatten_eligibility_mappings ( root) ;
47
47
@@ -132,7 +132,7 @@ impl Visitor for DisallowedUnevaluatedPropertiesVisitor {
132
132
}
133
133
}
134
134
135
- impl ScopedVisitor for DisallowedUnevaluatedPropertiesVisitor {
135
+ impl ScopedVisitor for DisallowUnevaluatedPropertiesVisitor {
136
136
fn push_schema_scope < S : Into < SchemaReference > > ( & mut self , scope : S ) {
137
137
self . scope_stack . push ( scope. into ( ) ) ;
138
138
}
@@ -237,12 +237,22 @@ fn build_closed_schema_flatten_eligibility_mappings(
237
237
Schema :: Object ( schema) => schema,
238
238
} ;
239
239
240
+ debug ! (
241
+ "Evaluating schema definition '{}' for markability." ,
242
+ definition_name
243
+ ) ;
244
+
240
245
// If a schema itself would not be considered markable, then we don't need to consider the
241
246
// eligibility between parent/child since there's nothing to drive the "now unmark the child
242
247
// schemas" logic.
243
248
if !is_markable_schema ( & root_schema. definitions , parent_schema) {
244
249
debug ! ( "Schema definition '{}' not markable." , definition_name) ;
245
250
continue ;
251
+ } else {
252
+ debug ! (
253
+ "Schema definition '{}' markable. Collecting referents." ,
254
+ definition_name
255
+ ) ;
246
256
}
247
257
248
258
// Collect all referents for this definition, which includes both property-based referents
@@ -251,6 +261,13 @@ fn build_closed_schema_flatten_eligibility_mappings(
251
261
let mut referents = HashSet :: new ( ) ;
252
262
get_referents ( parent_schema, & mut referents) ;
253
263
264
+ debug ! (
265
+ "Collected {} referents for '{}': {:?}" ,
266
+ referents. len( ) ,
267
+ definition_name,
268
+ referents
269
+ ) ;
270
+
254
271
// Store the parent/child mapping.
255
272
parent_to_child. insert ( SchemaReference :: from ( definition_name) , referents) ;
256
273
}
@@ -328,12 +345,14 @@ fn is_markable_schema(definitions: &Map<String, Schema>, schema: &SchemaObject)
328
345
// subschemas: { "type": "null" } and { "$ref": "#/definitions/T" }. If the schema for `T` is,
329
346
// say, just a scalar schema, instead of an object schema... then it wouldn't be marked, and in
330
347
// turn, we wouldn't need to mark the schema for `Option<T>`: there's no properties at all.
331
- //
332
- // We'll follow schema references in subschemas up to one level deep trying to figure this out.
333
348
if let Some ( subschema) = schema. subschemas . as_ref ( ) {
334
349
let subschemas = get_object_subschemas_from_parent ( subschema) . collect :: < Vec < _ > > ( ) ;
335
350
336
- let has_object_subschema = subschemas. iter ( ) . any ( |schema| is_object_schema ( schema) ) ;
351
+ debug ! ( "{} subschemas detected." , subschemas. len( ) ) ;
352
+
353
+ let has_object_subschema = subschemas
354
+ . iter ( )
355
+ . any ( |schema| is_markable_schema ( definitions, schema) ) ;
337
356
let has_referenced_object_subschema = subschemas
338
357
. iter ( )
339
358
. map ( |subschema| {
@@ -342,13 +361,33 @@ fn is_markable_schema(definitions: &Map<String, Schema>, schema: &SchemaObject)
342
361
. as_ref ( )
343
362
. and_then ( |reference| {
344
363
let reference = get_cleaned_schema_reference ( reference) ;
345
- definitions. get ( reference)
364
+ definitions. get_full ( reference)
365
+ } )
366
+ . and_then ( |( _, name, schema) | schema. as_object ( ) . map ( |schema| ( name, schema) ) )
367
+ . map_or ( false , |( name, schema) | {
368
+ debug ! (
369
+ "Following schema reference '{}' for subschema markability." ,
370
+ name
371
+ ) ;
372
+ is_markable_schema ( definitions, schema)
346
373
} )
347
- . and_then ( Schema :: as_object)
348
- . map_or ( false , is_object_schema)
349
374
} )
350
375
. any ( identity) ;
351
376
377
+ debug ! (
378
+ "Schema {} object subschema(s) and {} referenced subschemas." ,
379
+ if has_object_subschema {
380
+ "has"
381
+ } else {
382
+ "does not have"
383
+ } ,
384
+ if has_referenced_object_subschema {
385
+ "has"
386
+ } else {
387
+ "does not have"
388
+ } ,
389
+ ) ;
390
+
352
391
if has_object_subschema || has_referenced_object_subschema {
353
392
return true ;
354
393
}
@@ -504,7 +543,7 @@ mod tests {
504
543
505
544
use crate :: schema:: visitors:: test:: { as_schema, assert_schemas_eq} ;
506
545
507
- use super :: DisallowedUnevaluatedPropertiesVisitor ;
546
+ use super :: DisallowUnevaluatedPropertiesVisitor ;
508
547
509
548
#[ test]
510
549
fn basic_object_schema ( ) {
@@ -515,7 +554,7 @@ mod tests {
515
554
}
516
555
} ) ) ;
517
556
518
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
557
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
519
558
visitor. visit_root_schema ( & mut actual_schema) ;
520
559
521
560
let expected_schema = as_schema ( json ! ( {
@@ -543,7 +582,7 @@ mod tests {
543
582
}
544
583
} ) ) ;
545
584
546
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
585
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
547
586
visitor. visit_root_schema ( & mut actual_schema) ;
548
587
549
588
let expected_schema = as_schema ( json ! ( {
@@ -580,7 +619,7 @@ mod tests {
580
619
} ]
581
620
} ) ) ;
582
621
583
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
622
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
584
623
visitor. visit_root_schema ( & mut actual_schema) ;
585
624
586
625
let expected_schema = as_schema ( json ! ( {
@@ -621,7 +660,7 @@ mod tests {
621
660
} ]
622
661
} ) ) ;
623
662
624
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
663
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
625
664
visitor. visit_root_schema ( & mut actual_schema) ;
626
665
627
666
let expected_schema = as_schema ( json ! ( {
@@ -662,7 +701,7 @@ mod tests {
662
701
} ]
663
702
} ) ) ;
664
703
665
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
704
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
666
705
visitor. visit_root_schema ( & mut actual_schema) ;
667
706
668
707
let expected_schema = as_schema ( json ! ( {
@@ -696,7 +735,7 @@ mod tests {
696
735
} ) ) ;
697
736
let expected_schema = actual_schema. clone ( ) ;
698
737
699
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
738
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
700
739
visitor. visit_root_schema ( & mut actual_schema) ;
701
740
702
741
assert_schemas_eq ( expected_schema, actual_schema) ;
@@ -712,7 +751,7 @@ mod tests {
712
751
"additionalProperties" : false
713
752
} ) ) ;
714
753
715
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
754
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
716
755
visitor. visit_root_schema ( & mut actual_schema) ;
717
756
718
757
let expected_schema = as_schema ( json ! ( {
@@ -758,7 +797,7 @@ mod tests {
758
797
}
759
798
} ) ) ;
760
799
761
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
800
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
762
801
visitor. visit_root_schema ( & mut actual_schema) ;
763
802
764
803
let expected_schema = as_schema ( json ! ( {
@@ -813,7 +852,7 @@ mod tests {
813
852
}
814
853
} ) ) ;
815
854
816
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
855
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
817
856
visitor. visit_root_schema ( & mut actual_schema) ;
818
857
819
858
let expected_schema = as_schema ( json ! ( {
@@ -879,7 +918,7 @@ mod tests {
879
918
}
880
919
} ) ) ;
881
920
882
- let mut visitor = DisallowedUnevaluatedPropertiesVisitor :: default ( ) ;
921
+ let mut visitor = DisallowUnevaluatedPropertiesVisitor :: default ( ) ;
883
922
visitor. visit_root_schema ( & mut actual_schema) ;
884
923
885
924
// Expectations:
0 commit comments