@@ -251,8 +251,8 @@ impl<'py> Input<'py> for Bound<'py, PyAny> {
251251 str_as_int ( self , s)
252252 } else if self . is_exact_instance_of :: < PyFloat > ( ) {
253253 float_as_int ( self , self . extract :: < f64 > ( ) ?)
254- } else if let Ok ( decimal) = self . strict_decimal ( self . py ( ) ) {
255- decimal_as_int ( self , & decimal)
254+ } else if let Ok ( decimal) = self . validate_decimal ( true , self . py ( ) ) {
255+ decimal_as_int ( self , & decimal. into_inner ( ) )
256256 } else if let Ok ( float) = self . extract :: < f64 > ( ) {
257257 float_as_int ( self , float)
258258 } else if let Some ( enum_val) = maybe_as_enum ( self ) {
@@ -310,48 +310,44 @@ impl<'py> Input<'py> for Bound<'py, PyAny> {
310310 Err ( ValError :: new ( ErrorTypeDefaults :: FloatType , self ) )
311311 }
312312
313- fn strict_decimal ( & self , py : Python < ' py > ) -> ValResult < Bound < ' py , PyAny > > {
313+ fn validate_decimal ( & self , strict : bool , py : Python < ' py > ) -> ValMatch < Bound < ' py , PyAny > > {
314314 let decimal_type = get_decimal_type ( py) ;
315+
315316 // Fast path for existing decimal objects
316317 if self . is_exact_instance ( decimal_type) {
317- return Ok ( self . to_owned ( ) ) ;
318+ return Ok ( ValidationMatch :: exact ( self . to_owned ( ) . clone ( ) ) ) ;
319+ }
320+
321+ if !strict {
322+ if self . is_instance_of :: < PyString > ( ) || ( self . is_instance_of :: < PyInt > ( ) && !self . is_instance_of :: < PyBool > ( ) )
323+ {
324+ // Checking isinstance for str / int / bool is fast compared to decimal / float
325+ return create_decimal ( self , self ) . map ( ValidationMatch :: lax) ;
326+ }
327+
328+ if self . is_instance_of :: < PyFloat > ( ) {
329+ return create_decimal ( self . str ( ) ?. as_any ( ) , self ) . map ( ValidationMatch :: lax) ;
330+ }
318331 }
319332
320- // Try subclasses of decimals, they will be upcast to Decimal
321333 if self . is_instance ( decimal_type) ? {
322- return create_decimal ( self , self ) ;
334+ // Upcast subclasses to decimal
335+ return create_decimal ( self , self ) . map ( ValidationMatch :: strict) ;
323336 }
324337
325- Err ( ValError :: new (
338+ let error_type = if strict {
326339 ErrorType :: IsInstanceOf {
327340 class : decimal_type
328341 . qualname ( )
329342 . and_then ( |name| name. extract ( ) )
330343 . unwrap_or_else ( |_| "Decimal" . to_owned ( ) ) ,
331344 context : None ,
332- } ,
333- self ,
334- ) )
335- }
336-
337- fn lax_decimal ( & self , py : Python < ' py > ) -> ValResult < Bound < ' py , PyAny > > {
338- let decimal_type = get_decimal_type ( py) ;
339- // Fast path for existing decimal objects
340- if self . is_exact_instance ( decimal_type) {
341- return Ok ( self . to_owned ( ) . clone ( ) ) ;
342- }
343-
344- if self . is_instance_of :: < PyString > ( ) || ( self . is_instance_of :: < PyInt > ( ) && !self . is_instance_of :: < PyBool > ( ) ) {
345- // checking isinstance for str / int / bool is fast compared to decimal / float
346- create_decimal ( self , self )
347- } else if self . is_instance ( decimal_type) ? {
348- // upcast subclasses to decimal
349- return create_decimal ( self , self ) ;
350- } else if self . is_instance_of :: < PyFloat > ( ) {
351- create_decimal ( self . str ( ) ?. as_any ( ) , self )
345+ }
352346 } else {
353- Err ( ValError :: new ( ErrorTypeDefaults :: DecimalType , self ) )
354- }
347+ ErrorTypeDefaults :: DecimalType
348+ } ;
349+
350+ Err ( ValError :: new ( error_type, self ) )
355351 }
356352
357353 type Dict < ' a > = GenericPyMapping < ' a , ' py > where Self : ' a ;
0 commit comments