From a3aad016326a9526bd95c2c145252dd1880eb1d1 Mon Sep 17 00:00:00 2001 From: max143672 Date: Wed, 15 Nov 2023 22:47:06 +0400 Subject: [PATCH] Replace TryFrom with custom TryFromJsValue trait This commit replaces the usage of the standard library's TryFrom trait with a custom TryFromJsValue trait added for handling the conversion from JavaScript values in WASM. This trait has been implemented for different types across multiple modules to ensure consistent error handling on failed conversions. fixes #3685 --- crates/backend/src/codegen.rs | 12 +++++++----- src/convert/impls.rs | 6 +++--- src/convert/traits.rs | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 6c854e5e511c..2c9b16be3606 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -297,10 +297,10 @@ impl ToTokens for ast::Struct { } #[allow(clippy::all)] - impl #wasm_bindgen::__rt::core::convert::TryFrom<#wasm_bindgen::JsValue> for #name { + impl #wasm_bindgen::convert::TryFromJsValue for #name { type Error = #wasm_bindgen::JsValue; - fn try_from(value: #wasm_bindgen::JsValue) + fn try_from_js_value(value: #wasm_bindgen::JsValue) -> #wasm_bindgen::__rt::std::result::Result { let idx = #wasm_bindgen::convert::IntoWasmAbi::into_abi(&value); @@ -822,6 +822,7 @@ impl ToTokens for ast::ImportType { use #wasm_bindgen::convert::{IntoWasmAbi, FromWasmAbi}; use #wasm_bindgen::convert::{OptionIntoWasmAbi, OptionFromWasmAbi}; use #wasm_bindgen::convert::{RefFromWasmAbi, LongRefFromWasmAbi}; + use #wasm_bindgen::convert::TryFromJsValue; use #wasm_bindgen::describe::WasmDescribe; use #wasm_bindgen::{JsValue, JsCast, JsObject}; use #wasm_bindgen::__rt::core; @@ -1452,11 +1453,12 @@ impl ToTokens for ast::Enum { } #[allow(clippy::all)] - impl #wasm_bindgen::__rt::core::convert::TryFrom<#wasm_bindgen::JsValue> for #enum_name { + impl #wasm_bindgen::convert::TryFromJsValue for #enum_name { type Error = #wasm_bindgen::JsValue; - fn try_from(value: #wasm_bindgen::JsValue) - -> #wasm_bindgen::__rt::std::result::Result>::Error> { + fn try_from_js_value(value: #wasm_bindgen::JsValue) + -> #wasm_bindgen::__rt::std::result::Result::Error> { + use #wasm_bindgen::__rt::core::convert::TryFrom; let js = f64::try_from(&value)? as u32; #wasm_bindgen::__rt::std::result::Result::Ok( diff --git a/src/convert/impls.rs b/src/convert/impls.rs index 8c0c3c014bb2..8f1e37980559 100644 --- a/src/convert/impls.rs +++ b/src/convert/impls.rs @@ -2,13 +2,13 @@ use core::char; use core::mem::{self, ManuallyDrop}; use crate::convert::traits::{WasmAbi, WasmPrimitive}; +use crate::convert::TryFromJsValue; use crate::convert::{FromWasmAbi, IntoWasmAbi, LongRefFromWasmAbi, RefFromWasmAbi}; use crate::convert::{OptionFromWasmAbi, OptionIntoWasmAbi, ReturnWasmAbi}; use crate::{Clamped, JsError, JsValue, UnwrapThrowExt}; if_std! { use std::boxed::Box; - use std::convert::{TryFrom, TryInto}; use std::fmt::Debug; use std::vec::Vec; } @@ -415,7 +415,7 @@ if_std! { js_vals.into_abi() } - pub unsafe fn js_value_vector_from_abi>(js: as FromWasmAbi>::Abi) -> Box<[T]> where T::Error: Debug { + pub unsafe fn js_value_vector_from_abi(js: as FromWasmAbi>::Abi) -> Box<[T]> where T::Error: Debug { let js_vals = as FromWasmAbi>::from_abi(js); let mut result = Vec::with_capacity(js_vals.len()); @@ -430,7 +430,7 @@ if_std! { // we're talking about, it can only see functions that actually make it to the // final wasm binary (i.e., not inlined functions). All of those internal // iterator functions get inlined in release mode, and so they don't show up. - result.push(value.try_into().expect_throw("array contains a value of the wrong type")); + result.push(T::try_from_js_value(value).expect_throw("array contains a value of the wrong type")); } result.into_boxed_slice() } diff --git a/src/convert/traits.rs b/src/convert/traits.rs index fd06c3adba30..24b94c947bfd 100644 --- a/src/convert/traits.rs +++ b/src/convert/traits.rs @@ -1,7 +1,9 @@ use core::borrow::Borrow; use core::ops::{Deref, DerefMut}; +use std::convert::TryFrom; use crate::describe::*; +use crate::JsValue; /// A trait for anything that can be converted into a type that can cross the /// wasm ABI directly, eg `u32` or `f64`. @@ -249,3 +251,19 @@ impl WasmRet { T::join(self.prim1, self.prim2, self.prim3, self.prim4) } } + +pub trait TryFromJsValue: Sized { + /// The type returned in the event of a conversion error. + type Error; + + /// Performs the conversion. + fn try_from_js_value(value: JsValue) -> Result; +} + +impl> TryFromJsValue for T { + type Error = T::Error; + + fn try_from_js_value(value: JsValue) -> Result { + Self::try_from(value) + } +}