@@ -67,7 +67,6 @@ impl SchemaValidator {
6767
6868 let mut build_context = BuildContext :: default ( ) ;
6969 let ( mut validator, _) = build_validator ( schema, config, & mut build_context) ?;
70- build_context. complete_validators ( ) ?;
7170 validator. complete ( & build_context) ?;
7271 let slots = build_context. into_slots ( ) ?;
7372 let title = validator. get_name ( ) . into_py ( py) ;
@@ -459,65 +458,68 @@ pub trait Validator: Send + Sync + Clone + Debug {
459458 }
460459}
461460
461+ /// `BuildContext` is used to store extra information while building validators,
462+ /// currently it just holds a vec "slots" which holds validators need to be accessed from multiple other validators
463+ /// and therefore can't be owned by them directly.
462464#[ derive( Default , Clone ) ]
463465pub struct BuildContext {
464466 slots : Vec < ( String , Option < CombinedValidator > ) > ,
465467}
466468
467469impl BuildContext {
470+ /// First of two part process to add a new validator slot, we add the `slot_ref` to the array, but not the
471+ /// actual `validator`, we can't add the validator until it's build.
472+ /// We need the `id` to build the validator, hence this two-step process.
468473 pub fn prepare_slot ( & mut self , slot_ref : String ) -> PyResult < usize > {
469474 let id = self . slots . len ( ) ;
470475 self . slots . push ( ( slot_ref, None ) ) ;
471476 Ok ( id)
472477 }
473478
479+ /// Second part of adding a validator - we update the slot to include a validator
474480 pub fn complete_slot ( & mut self , slot_id : usize , validator : CombinedValidator ) -> PyResult < ( ) > {
475481 match self . slots . get ( slot_id) {
476482 Some ( ( val_ref, _) ) => {
477483 self . slots [ slot_id] = ( val_ref. clone ( ) , Some ( validator) ) ;
478484 Ok ( ( ) )
479485 }
480- None => py_error ! ( "Recursive reference error : slot {} not found" , slot_id) ,
486+ None => py_error ! ( "Slots Error : slot {} not found" , slot_id) ,
481487 }
482488 }
483489
484- pub fn find_slot_id ( & self , val_ref : & str ) -> PyResult < usize > {
485- let is_match = |( slot_ref, _) : & ( String , Option < CombinedValidator > ) | slot_ref == val_ref;
490+ /// find a slot by `slot_ref` - iterate over the slots until we find a matching reference - return the index
491+ pub fn find_slot_id ( & self , slot_ref : & str ) -> PyResult < usize > {
492+ let is_match = |( match_sr, _) : & ( String , Option < CombinedValidator > ) | match_sr == slot_ref;
486493 match self . slots . iter ( ) . position ( is_match) {
487494 Some ( id) => Ok ( id) ,
488- None => py_error ! ( "Recursive reference error : ref '{}' not found" , val_ref ) ,
495+ None => py_error ! ( "Slots Error : ref '{}' not found" , slot_ref ) ,
489496 }
490497 }
491498
492- pub fn get_validator ( & self , slot_id : usize ) -> PyResult < & CombinedValidator > {
499+ /// find a validator by `slot_id` - this used in `Validator.complete`, specifically `RecursiveRefValidator`
500+ /// to set its name
501+ pub fn find_validator ( & self , slot_id : usize ) -> PyResult < & CombinedValidator > {
493502 match self . slots . get ( slot_id) {
494503 Some ( ( _, op_validator) ) => match op_validator {
495504 Some ( ref validator) => Ok ( validator) ,
496- None => py_error ! ( "Recursive reference error : slot {} not yet filled" , slot_id) ,
505+ None => py_error ! ( "Slots Error : slot {} not yet filled" , slot_id) ,
497506 } ,
498- None => py_error ! ( "Recursive reference error : slot {} not found" , slot_id) ,
507+ None => py_error ! ( "Slots Error : slot {} not found" , slot_id) ,
499508 }
500509 }
501510
502- pub fn complete_validators ( & mut self ) -> PyResult < ( ) > {
503- let self_clone = self . clone ( ) ;
504- for ( _, op_validator) in self . slots . iter_mut ( ) {
505- match op_validator {
506- Some ( ref mut validator) => {
507- validator. complete ( & self_clone) ?;
508- }
509- None => return py_error ! ( "Recursive reference error: slot not yet filled" ) ,
510- }
511- }
512- Ok ( ( ) )
513- }
514-
511+ /// Move validators into a new vec which maintains the order of slots, `complete` is called on each validator
512+ /// at the same time.
515513 pub fn into_slots ( self ) -> PyResult < Vec < CombinedValidator > > {
514+ let self_clone = self . clone ( ) ;
516515 self . slots
517516 . into_iter ( )
518517 . map ( |( _, opt_validator) | match opt_validator {
519- Some ( validator) => Ok ( validator) ,
520- None => py_error ! ( "Recursive schema build error: slot not yet filled" ) ,
518+ Some ( mut validator) => {
519+ validator. complete ( & self_clone) ?;
520+ Ok ( validator)
521+ }
522+ None => py_error ! ( "Slots Error: slot not yet filled" ) ,
521523 } )
522524 . collect ( )
523525 }
0 commit comments