@@ -40,12 +40,9 @@ macro_rules! externs {
40
40
)
41
41
}
42
42
43
- pub trait JsTryFrom < T > : Sized {
44
- /// The type returned in the event of a conversion error.
45
- type Error ;
46
-
43
+ pub trait TryFromJsValue : Sized {
47
44
/// Performs the conversion.
48
- fn try_from ( value : T ) -> Result < Self , Self :: Error > ;
45
+ fn try_from ( value : JsValue ) -> Result < Self , TypeMismatch > ;
49
46
}
50
47
51
48
/// A module which is typically glob imported from:
@@ -448,29 +445,24 @@ where
448
445
}
449
446
}
450
447
451
- impl JsTryFrom < JsValue > for bool {
452
- type Error = TypeMismatch ;
453
-
454
- fn try_from ( value : JsValue ) -> Result < Self , Self :: Error > {
448
+ impl TryFromJsValue for bool {
449
+ fn try_from ( value : JsValue ) -> Result < Self , TypeMismatch > {
455
450
value. as_bool ( ) . ok_or ( TypeMismatch )
456
451
}
457
452
}
458
453
459
- impl JsTryFrom < JsValue > for String {
460
- type Error = TypeMismatch ;
461
-
462
- fn try_from ( value : JsValue ) -> Result < Self , Self :: Error > {
454
+ impl TryFromJsValue for String {
455
+ fn try_from ( value : JsValue ) -> Result < Self , TypeMismatch > {
463
456
value. as_string ( ) . ok_or ( TypeMismatch )
464
457
}
465
458
}
466
459
467
- impl < T > JsTryFrom < JsValue > for Option < T >
460
+ // This would not be possible if we used `std::convert::TryFrom`.
461
+ impl < T > TryFromJsValue for Option < T >
468
462
where
469
- T : JsTryFrom < JsValue , Error = TypeMismatch > ,
463
+ T : TryFromJsValue ,
470
464
{
471
- type Error = TypeMismatch ;
472
-
473
- fn try_from ( value : JsValue ) -> Result < Self , Self :: Error > {
465
+ fn try_from ( value : JsValue ) -> Result < Self , TypeMismatch > {
474
466
if value. is_null ( ) || value. is_undefined ( ) {
475
467
return Ok ( None ) ;
476
468
} else {
@@ -479,13 +471,11 @@ where
479
471
}
480
472
}
481
473
482
- impl < T > JsTryFrom < JsValue > for T
474
+ impl < T > TryFromJsValue for T
483
475
where
484
476
T : JsCast ,
485
477
{
486
- type Error = TypeMismatch ;
487
-
488
- fn try_from ( value : JsValue ) -> Result < Self , Self :: Error > {
478
+ fn try_from ( value : JsValue ) -> Result < Self , TypeMismatch > {
489
479
value. dyn_into ( ) . map_err ( |_| TypeMismatch )
490
480
}
491
481
}
@@ -538,12 +528,17 @@ numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
538
528
539
529
macro_rules! integers {
540
530
( $( $n: ident) * ) => ( $(
541
- impl JsTryFrom <JsValue > for $n {
542
- type Error = TypeMismatch ;
543
-
544
- fn try_from( value: JsValue ) -> Result <Self , Self :: Error > {
531
+ impl TryFromJsValue for $n {
532
+ fn try_from( value: JsValue ) -> Result <Self , TypeMismatch > {
533
+ const MAX_SAFE_JS_INT : f64 = 9_007_199_254_740_991.0 ; //(2^53 - 1)
545
534
let value = value. as_f64( ) . ok_or( TypeMismatch ) ?;
546
- if value > $n:: max_value( ) as f64 || value < $n:: min_value( ) as f64 {
535
+ // https://doc.rust-lang.org/1.30.0/book/first-edition/casting-between-types.html
536
+ if ! value. is_normal( )
537
+ || value > $n:: max_value( ) as f64
538
+ || value < $n:: min_value( ) as f64
539
+ || value. abs( ) > MAX_SAFE_JS_INT
540
+ || value != value. floor( )
541
+ {
547
542
return Err ( TypeMismatch ) ;
548
543
}
549
544
Ok ( value as $n)
@@ -556,10 +551,8 @@ integers! { i8 u8 i16 u16 i32 u32 }
556
551
557
552
macro_rules! floats {
558
553
( $( $n: ident) * ) => ( $(
559
- impl JsTryFrom <JsValue > for $n {
560
- type Error = TypeMismatch ;
561
-
562
- fn try_from( value: JsValue ) -> Result <Self , Self :: Error > {
554
+ impl TryFromJsValue for $n {
555
+ fn try_from( value: JsValue ) -> Result <Self , TypeMismatch > {
563
556
let value = value. as_f64( ) . ok_or( TypeMismatch ) ?;
564
557
Ok ( value as $n)
565
558
}
0 commit comments