-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable passing String and custom struct boxed slices across ABI and implement TryFrom<JsValue> for custom structs #2734
Changes from all commits
bfb3770
cba7428
833c37f
e0bcda0
e5c9e0e
10d6985
b24efb7
af0c6a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,8 +4,16 @@ use core::mem::{self, ManuallyDrop}; | |
use crate::convert::traits::WasmAbi; | ||
use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi}; | ||
use crate::convert::{OptionFromWasmAbi, OptionIntoWasmAbi, ReturnWasmAbi}; | ||
use crate::describe::{self, WasmDescribe}; | ||
use crate::{Clamped, JsError, JsValue}; | ||
|
||
if_std! { | ||
use std::boxed::Box; | ||
use std::convert::{TryFrom, TryInto}; | ||
use std::vec::Vec; | ||
use crate::convert::JsValueVector; | ||
} | ||
|
||
unsafe impl WasmAbi for () {} | ||
|
||
#[repr(C)] | ||
|
@@ -465,6 +473,43 @@ impl<T: IntoWasmAbi, E: Into<JsValue>> ReturnWasmAbi for Result<T, E> { | |
} | ||
} | ||
|
||
if_std! { | ||
impl<T> JsValueVector for Box<[T]> where | ||
T: Into<JsValue> + TryFrom<JsValue>, | ||
<T as TryFrom<JsValue>>::Error: core::fmt::Debug { | ||
type ToAbi = <Box<[JsValue]> as IntoWasmAbi>::Abi; | ||
type FromAbi = <Box<[JsValue]> as FromWasmAbi>::Abi; | ||
|
||
fn describe() { | ||
describe::inform(describe::VECTOR); | ||
JsValue::describe(); | ||
} | ||
|
||
fn into_abi(self) -> Self::ToAbi { | ||
let js_vals: Box::<[JsValue]> = self | ||
.into_vec() | ||
.into_iter() | ||
.map(|x| x.into()) | ||
.collect(); | ||
Comment on lines
+489
to
+493
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels kind of wrong to be throwing away the initial allocation and making a new one here, but it works for an MVP and can be optimised later if necessary. I have some ideas how this can be avoided by doing more work in JS, but I have no idea if that'd actually end up being faster, so let's just go with this for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly my thinking, let's not let perfect be the enemy of good. |
||
|
||
IntoWasmAbi::into_abi(js_vals) | ||
} | ||
|
||
fn none() -> Self::ToAbi { | ||
<Box<[JsValue]> as OptionIntoWasmAbi>::none() | ||
} | ||
|
||
unsafe fn from_abi(js: Self::FromAbi) -> Self { | ||
let js_vals = <Vec<JsValue> as FromWasmAbi>::from_abi(js); | ||
|
||
js_vals | ||
.into_iter() | ||
.filter_map(|x| x.try_into().ok()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels like a bad idea to silently throw away array elements that fail to be converted; I'd prefer if this used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. No idea why I did this tbh. I thought I made it so it would panic. |
||
.collect() | ||
} | ||
} | ||
} | ||
|
||
impl IntoWasmAbi for JsError { | ||
type Abi = <JsValue as IntoWasmAbi>::Abi; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not great practice to use
()
as an error type. Normally I'd probably suggest creating a new error type for this, but all ofwasm-bindgen
's existingTryFrom<JsValue>
impls useJsValue
for their error type and so I think it's a better idea to keep things consistent.