@@ -2,8 +2,10 @@ use pyo3::intern;
22use pyo3:: prelude:: * ;
33use pyo3:: types:: PyDict ;
44
5- use crate :: errors:: ValResult ;
6- use crate :: input:: Input ;
5+ use jiter:: JsonValue ;
6+
7+ use crate :: errors:: { ErrorType , ErrorTypeDefaults , ValError , ValLineError , ValResult } ;
8+ use crate :: input:: { EitherBytes , Input , ValidationMatch } ;
79use crate :: tools:: SchemaDict ;
810
911use super :: { build_validator, BuildValidator , CombinedValidator , DefinitionsBuilder , ValidationState , Validator } ;
@@ -50,17 +52,52 @@ impl Validator for JsonValidator {
5052 input : & ' data impl Input < ' data > ,
5153 state : & mut ValidationState ,
5254 ) -> ValResult < PyObject > {
53- let json_value = input. parse_json ( ) ?;
55+ let v_match = validate_json_bytes ( input) ?;
56+ let json_either_bytes = v_match. unpack ( state) ;
57+ let json_bytes = json_either_bytes. as_slice ( ) ;
5458 match self . validator {
55- Some ( ref validator) => match validator. validate ( py, & json_value, state) {
56- Ok ( v) => Ok ( v) ,
57- Err ( err) => Err ( err) ,
58- } ,
59- None => Ok ( json_value. to_object ( py) ) ,
59+ Some ( ref validator) => {
60+ let json_value = JsonValue :: parse ( json_bytes, true ) . map_err ( |e| map_json_err ( input, e, json_bytes) ) ?;
61+ validator. validate ( py, & json_value, state)
62+ }
63+ None => {
64+ let obj =
65+ jiter:: python_parse ( py, json_bytes, true , true ) . map_err ( |e| map_json_err ( input, e, json_bytes) ) ?;
66+ Ok ( obj)
67+ }
6068 }
6169 }
6270
6371 fn get_name ( & self ) -> & str {
6472 & self . name
6573 }
6674}
75+
76+ pub fn validate_json_bytes < ' data > ( input : & ' data impl Input < ' data > ) -> ValResult < ValidationMatch < EitherBytes < ' data > > > {
77+ match input. validate_bytes ( false ) {
78+ Ok ( v_match) => Ok ( v_match) ,
79+ Err ( ValError :: LineErrors ( e) ) => Err ( ValError :: LineErrors (
80+ e. into_iter ( ) . map ( map_bytes_error) . collect :: < Vec < _ > > ( ) ,
81+ ) ) ,
82+ Err ( e) => Err ( e) ,
83+ }
84+ }
85+
86+ fn map_bytes_error ( line_error : ValLineError ) -> ValLineError {
87+ match line_error. error_type {
88+ ErrorType :: BytesType { .. } => {
89+ ValLineError :: new_custom_input ( ErrorTypeDefaults :: JsonType , line_error. input_value )
90+ }
91+ _ => line_error,
92+ }
93+ }
94+
95+ pub fn map_json_err < ' a > ( input : & ' a impl Input < ' a > , error : jiter:: JsonError , json_bytes : & [ u8 ] ) -> ValError {
96+ ValError :: new (
97+ ErrorType :: JsonInvalid {
98+ error : error. description ( json_bytes) ,
99+ context : None ,
100+ } ,
101+ input,
102+ )
103+ }
0 commit comments