Skip to content

Commit afdbda2

Browse files
Implement To/FromWasmAbi traits for boxed slices of JsValue wrappers
1 parent eb855e3 commit afdbda2

File tree

4 files changed

+46
-2
lines changed

4 files changed

+46
-2
lines changed

crates/backend/src/codegen.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ impl ToTokens for ast::ImportType {
624624
use wasm_bindgen::convert::{OptionIntoWasmAbi, OptionFromWasmAbi};
625625
use wasm_bindgen::convert::RefFromWasmAbi;
626626
use wasm_bindgen::describe::WasmDescribe;
627-
use wasm_bindgen::{JsValue, JsCast};
627+
use wasm_bindgen::{JsValue, JsCast, JsObject};
628628
use wasm_bindgen::__rt::core;
629629

630630
impl WasmDescribe for #rust_name {
@@ -761,6 +761,8 @@ impl ToTokens for ast::ImportType {
761761
}
762762
}
763763

764+
impl JsObject for #rust_name {}
765+
764766
()
765767
};
766768
})

src/cast.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::JsValue;
1+
use crate::{describe::WasmDescribe, JsValue};
22

33
/// A trait for checked and unchecked casting between JS types.
44
///
@@ -154,3 +154,6 @@ where
154154
/// won't need to call this.
155155
fn unchecked_from_js_ref(val: &JsValue) -> &Self;
156156
}
157+
158+
/// Trait implemented for wrappers around `JsValue`s generated by `#[wasm_bindgen]`.
159+
pub trait JsObject: JsCast + WasmDescribe {}

src/convert/slices.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::prelude::v1::*;
44
use core::slice;
55
use core::str;
66

7+
use crate::cast::JsObject;
78
use crate::convert::OptionIntoWasmAbi;
89
use crate::convert::{FromWasmAbi, IntoWasmAbi, RefFromWasmAbi, RefMutFromWasmAbi, WasmAbi};
910
use cfg_if::cfg_if;
@@ -270,4 +271,41 @@ if_std! {
270271
#[inline]
271272
fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
272273
}
274+
275+
impl<T> IntoWasmAbi for Box<[T]> where T: JsObject {
276+
type Abi = WasmSlice;
277+
278+
#[inline]
279+
fn into_abi(self) -> WasmSlice {
280+
let ptr = self.as_ptr();
281+
let len = self.len();
282+
mem::forget(self);
283+
WasmSlice {
284+
ptr: ptr.into_abi(),
285+
len: len as u32,
286+
}
287+
}
288+
}
289+
290+
impl<T> OptionIntoWasmAbi for Box<[T]> where T: JsObject {
291+
#[inline]
292+
fn none() -> WasmSlice { null_slice() }
293+
}
294+
295+
impl<T> FromWasmAbi for Box<[T]> where T: JsObject {
296+
type Abi = WasmSlice;
297+
298+
#[inline]
299+
unsafe fn from_abi(js: WasmSlice) -> Self {
300+
let ptr = <*mut JsValue>::from_abi(js.ptr);
301+
let len = js.len as usize;
302+
let vec: Vec<T> = Vec::from_raw_parts(ptr, len, len).drain(..).map(|js_value| T::unchecked_from_js(js_value)).collect();
303+
return vec.into_boxed_slice();
304+
}
305+
}
306+
307+
impl<T> OptionFromWasmAbi for Box<[T]> where T: JsObject {
308+
#[inline]
309+
fn is_none(slice: &WasmSlice) -> bool { slice.ptr == 0 }
310+
}
273311
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub mod describe;
6363

6464
mod cast;
6565
pub use crate::cast::JsCast;
66+
pub use crate::cast::JsObject;
6667

6768
if_std! {
6869
extern crate std;

0 commit comments

Comments
 (0)