@@ -251,8 +251,8 @@ impl<'py> Input<'py> for Bound<'py, PyAny> {
251
251
str_as_int ( self , s)
252
252
} else if self . is_exact_instance_of :: < PyFloat > ( ) {
253
253
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 ( ) )
256
256
} else if let Ok ( float) = self . extract :: < f64 > ( ) {
257
257
float_as_int ( self , float)
258
258
} else if let Some ( enum_val) = maybe_as_enum ( self ) {
@@ -310,48 +310,44 @@ impl<'py> Input<'py> for Bound<'py, PyAny> {
310
310
Err ( ValError :: new ( ErrorTypeDefaults :: FloatType , self ) )
311
311
}
312
312
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 > > {
314
314
let decimal_type = get_decimal_type ( py) ;
315
+
315
316
// Fast path for existing decimal objects
316
317
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
+ }
318
331
}
319
332
320
- // Try subclasses of decimals, they will be upcast to Decimal
321
333
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) ;
323
336
}
324
337
325
- Err ( ValError :: new (
338
+ let error_type = if strict {
326
339
ErrorType :: IsInstanceOf {
327
340
class : decimal_type
328
341
. qualname ( )
329
342
. and_then ( |name| name. extract ( ) )
330
343
. unwrap_or_else ( |_| "Decimal" . to_owned ( ) ) ,
331
344
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
+ }
352
346
} else {
353
- Err ( ValError :: new ( ErrorTypeDefaults :: DecimalType , self ) )
354
- }
347
+ ErrorTypeDefaults :: DecimalType
348
+ } ;
349
+
350
+ Err ( ValError :: new ( error_type, self ) )
355
351
}
356
352
357
353
type Dict < ' a > = GenericPyMapping < ' a , ' py > where Self : ' a ;
0 commit comments