@@ -7,12 +7,14 @@ use crate::errors::{ErrorKind, ValError, ValResult};
77use crate :: input:: { Input , JsonType } ;
88use crate :: recursion_guard:: RecursionGuard ;
99
10+ use super :: function:: convert_err;
1011use super :: { BuildContext , BuildValidator , CombinedValidator , Extra , Validator } ;
1112
1213#[ derive( Debug , Clone ) ]
1314pub struct IsInstanceValidator {
1415 class : Py < PyType > ,
1516 json_types : u8 ,
17+ json_function : Option < PyObject > ,
1618 class_repr : String ,
1719 name : String ,
1820}
@@ -25,16 +27,18 @@ impl BuildValidator for IsInstanceValidator {
2527 _config : Option < & PyDict > ,
2628 _build_context : & mut BuildContext ,
2729 ) -> PyResult < CombinedValidator > {
28- let class: & PyType = schema. get_as_req ( intern ! ( schema. py( ) , "cls" ) ) ?;
30+ let py = schema. py ( ) ;
31+ let class: & PyType = schema. get_as_req ( intern ! ( py, "cls" ) ) ?;
2932 let class_repr = class. name ( ) ?. to_string ( ) ;
3033 let name = format ! ( "{}[{}]" , Self :: EXPECTED_TYPE , class_repr) ;
31- let json_types = match schema. get_as :: < & PySet > ( intern ! ( schema . py ( ) , "json_types" ) ) ? {
34+ let json_types = match schema. get_as :: < & PySet > ( intern ! ( py , "json_types" ) ) ? {
3235 Some ( s) => JsonType :: combine ( s) ?,
3336 None => 0 ,
3437 } ;
3538 Ok ( Self {
3639 class : class. into ( ) ,
3740 json_types,
41+ json_function : schema. get_item ( intern ! ( py, "json_function" ) ) . map ( |f| f. into_py ( py) ) ,
3842 class_repr,
3943 name,
4044 }
@@ -52,7 +56,16 @@ impl Validator for IsInstanceValidator {
5256 _recursion_guard : & ' s mut RecursionGuard ,
5357 ) -> ValResult < ' data , PyObject > {
5458 match input. is_instance ( self . class . as_ref ( py) , self . json_types ) ? {
55- true => Ok ( input. to_object ( py) ) ,
59+ true => {
60+ if input. get_type ( ) . is_json ( ) {
61+ if let Some ( ref json_function) = self . json_function {
62+ return json_function
63+ . call1 ( py, ( input. to_object ( py) , ) )
64+ . map_err ( |e| convert_err ( py, e, input) ) ;
65+ }
66+ }
67+ Ok ( input. to_object ( py) )
68+ }
5669 false => Err ( ValError :: new (
5770 ErrorKind :: IsInstanceOf {
5871 class : self . class_repr . clone ( ) ,
0 commit comments