Skip to content

Commit 3246c80

Browse files
committed
Make the TryFrom trait more specific.
1 parent cb53965 commit 3246c80

File tree

3 files changed

+30
-40
lines changed

3 files changed

+30
-40
lines changed

crates/backend/src/codegen.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -888,9 +888,7 @@ impl ToTokens for ast::ImportEnum {
888888
}
889889

890890
#[allow(clippy::all)]
891-
impl wasm_bindgen::JsTryFrom<wasm_bindgen::JsValue> for #name {
892-
type Error = wasm_bindgen::TypeMismatch;
893-
891+
impl wasm_bindgen::TryFromJsValue for #name {
894892
fn try_from(value: wasm_bindgen::JsValue) -> Result<Self, wasm_bindgen::TypeMismatch> {
895893
Ok(match value.as_string().ok_or(wasm_bindgen::TypeMismatch)?.as_str() {
896894
#(#variant_strings => #variant_paths_ref,)*
@@ -1545,7 +1543,7 @@ fn iterable(rust_name: Option<&Ident>, iterable: &ast::Iterable) -> TokenStream
15451543
ast::Iterable::TypedMap { key, value } => {
15461544
quote! {
15471545
pub fn iter(&self) -> impl std::iter::Iterator<Item=(#key, #value)> {
1548-
use wasm_bindgen::{UnwrapThrowExt, JsCast, JsTryFrom};
1546+
use wasm_bindgen::{UnwrapThrowExt, JsCast, TryFromJsValue};
15491547
struct Iter(js_sys::Iterator);
15501548

15511549
impl Iterator for Iter {
@@ -1561,8 +1559,8 @@ fn iterable(rust_name: Option<&Ident>, iterable: &ast::Iterable) -> TokenStream
15611559
let key = entry.get(0);
15621560
let value = entry.get(1);
15631561
Some((
1564-
JsTryFrom::try_from(key).unwrap_throw(),
1565-
JsTryFrom::try_from(value).unwrap_throw()
1562+
TryFromJsValue::try_from(key).unwrap_throw(),
1563+
TryFromJsValue::try_from(value).unwrap_throw()
15661564
))
15671565
}
15681566
}
@@ -1574,7 +1572,7 @@ fn iterable(rust_name: Option<&Ident>, iterable: &ast::Iterable) -> TokenStream
15741572
ast::Iterable::Typed(value) => {
15751573
quote! {
15761574
pub fn iter(&self) -> impl std::iter::Iterator<Item=#value> {
1577-
use wasm_bindgen::{UnwrapThrowExt, JsCast, JsTryFrom};
1575+
use wasm_bindgen::{UnwrapThrowExt, JsCast, TryFromJsValue};
15781576
struct Iter(js_sys::Iterator);
15791577

15801578
impl Iterator for Iter {
@@ -1584,7 +1582,7 @@ fn iterable(rust_name: Option<&Ident>, iterable: &ast::Iterable) -> TokenStream
15841582
if next.done() {
15851583
return None; // We discard the end value here.
15861584
}
1587-
Some(JsTryFrom::try_from(next.value()).unwrap_throw())
1585+
Some(TryFromJsValue::try_from(next.value()).unwrap_throw())
15881586
}
15891587
}
15901588

crates/web-sys/tests/wasm/headers.rs

-1
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,3 @@ fn headers() {
4444
assert_eq!(value, "text/plain");
4545
}
4646
}
47-

src/lib.rs

+24-31
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,9 @@ macro_rules! externs {
4040
)
4141
}
4242

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 {
4744
/// Performs the conversion.
48-
fn try_from(value: T) -> Result<Self, Self::Error>;
45+
fn try_from(value: JsValue) -> Result<Self, TypeMismatch>;
4946
}
5047

5148
/// A module which is typically glob imported from:
@@ -448,29 +445,24 @@ where
448445
}
449446
}
450447

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> {
455450
value.as_bool().ok_or(TypeMismatch)
456451
}
457452
}
458453

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> {
463456
value.as_string().ok_or(TypeMismatch)
464457
}
465458
}
466459

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>
468462
where
469-
T: JsTryFrom<JsValue, Error = TypeMismatch>,
463+
T: TryFromJsValue,
470464
{
471-
type Error = TypeMismatch;
472-
473-
fn try_from(value: JsValue) -> Result<Self, Self::Error> {
465+
fn try_from(value: JsValue) -> Result<Self, TypeMismatch> {
474466
if value.is_null() || value.is_undefined() {
475467
return Ok(None);
476468
} else {
@@ -479,13 +471,11 @@ where
479471
}
480472
}
481473

482-
impl<T> JsTryFrom<JsValue> for T
474+
impl<T> TryFromJsValue for T
483475
where
484476
T: JsCast,
485477
{
486-
type Error = TypeMismatch;
487-
488-
fn try_from(value: JsValue) -> Result<Self, Self::Error> {
478+
fn try_from(value: JsValue) -> Result<Self, TypeMismatch> {
489479
value.dyn_into().map_err(|_| TypeMismatch)
490480
}
491481
}
@@ -538,12 +528,17 @@ numbers! { i8 u8 i16 u16 i32 u32 f32 f64 }
538528

539529
macro_rules! integers {
540530
($($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)
545534
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+
{
547542
return Err(TypeMismatch);
548543
}
549544
Ok(value as $n)
@@ -556,10 +551,8 @@ integers! { i8 u8 i16 u16 i32 u32 }
556551

557552
macro_rules! floats {
558553
($($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> {
563556
let value = value.as_f64().ok_or(TypeMismatch)?;
564557
Ok(value as $n)
565558
}

0 commit comments

Comments
 (0)