Skip to content
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

Added support for VectorIntoWasmAbi and VectorFromWasmAbi #41

Merged
merged 12 commits into from
Aug 5, 2024
6 changes: 1 addition & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ categories = ["wasm"]
[dependencies]
tsify-next-macros = { path = "tsify-next-macros", version = "0.5.3" }
wasm-bindgen = { version = "0.2.86", optional = true }
serde = { version = "1.0", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
serde-wasm-bindgen = { version = "0.6", optional = true }
gloo-utils = { version = "0.2", optional = true }
Expand All @@ -26,10 +26,6 @@ indoc = "2.0.5"
js-sys = "0.3"
macrotest = "1.0"
pretty_assertions = "1.4.0"
serde = { version = "1.0", features = ["derive"] }
serde-wasm-bindgen = "0.6"
serde_json = "1.0"
wasm-bindgen = "0.2"
wasm-bindgen-test = "0.3"

[features]
Expand Down
12 changes: 12 additions & 0 deletions tests-e2e/reference_output/test1/test1.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
/* tslint:disable */
/* eslint-disable */
/**
* @param {Point} point
*/
export function consume(point: Point): void;
/**
* @returns {Point}
*/
export function into_js(): Point;
/**
* @param {(Point)[]} points
*/
export function consume_vector(points: (Point)[]): void;
/**
* @returns {(Point)[]}
*/
export function vector_into_js(): (Point)[];
export interface Point {
x: number;
y: number;
Expand Down
15 changes: 15 additions & 0 deletions tests-e2e/test1/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,22 @@ pub struct Point {
y: i32,
}

#[wasm_bindgen]
pub fn consume(point: Point) {}

#[wasm_bindgen]
pub fn into_js() -> Point {
Point { x: 0, y: 0 }
}

#[wasm_bindgen]
pub fn consume_vector(points: Vec<Point>) {}

#[wasm_bindgen]
pub fn vector_into_js() -> Vec<Point> {
vec![
Point { x: 1, y: 6 },
Point { x: 2, y: 5 },
Point { x: 3, y: 4 },
]
}
eneoli marked this conversation as resolved.
Show resolved Hide resolved
231 changes: 75 additions & 156 deletions tests/expand/borrow.expanded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,164 +11,15 @@ const _: () = {
use tsify_next::Tsify;
use wasm_bindgen::{
convert::{
FromWasmAbi, IntoWasmAbi, OptionFromWasmAbi, OptionIntoWasmAbi,
RefFromWasmAbi,
FromWasmAbi, VectorFromWasmAbi, IntoWasmAbi, VectorIntoWasmAbi,
OptionFromWasmAbi, OptionIntoWasmAbi, RefFromWasmAbi,
},
describe::WasmDescribe, prelude::*,
describe::WasmDescribe, describe::WasmDescribeVector, prelude::*,
};
#[automatically_derived]
///
#[repr(transparent)]
pub struct JsType {
obj: wasm_bindgen::JsValue,
}
#[automatically_derived]
const _: () = {
use wasm_bindgen::convert::TryFromJsValue;
use wasm_bindgen::convert::{IntoWasmAbi, FromWasmAbi};
use wasm_bindgen::convert::{OptionIntoWasmAbi, OptionFromWasmAbi};
use wasm_bindgen::convert::{RefFromWasmAbi, LongRefFromWasmAbi};
use wasm_bindgen::describe::WasmDescribe;
use wasm_bindgen::{JsValue, JsCast, JsObject};
use wasm_bindgen::__rt::core;
impl WasmDescribe for JsType {
fn describe() {
use wasm_bindgen::describe::*;
inform(NAMED_EXTERNREF);
inform(6u32);
inform(66u32);
inform(111u32);
inform(114u32);
inform(114u32);
inform(111u32);
inform(119u32);
}
}
impl IntoWasmAbi for JsType {
type Abi = <JsValue as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self) -> Self::Abi {
self.obj.into_abi()
}
}
impl OptionIntoWasmAbi for JsType {
#[inline]
fn none() -> Self::Abi {
0
}
}
impl<'a> OptionIntoWasmAbi for &'a JsType {
#[inline]
fn none() -> Self::Abi {
0
}
}
impl FromWasmAbi for JsType {
type Abi = <JsValue as FromWasmAbi>::Abi;
#[inline]
unsafe fn from_abi(js: Self::Abi) -> Self {
JsType {
obj: JsValue::from_abi(js).into(),
}
}
}
impl OptionFromWasmAbi for JsType {
#[inline]
fn is_none(abi: &Self::Abi) -> bool {
*abi == 0
}
}
impl<'a> IntoWasmAbi for &'a JsType {
type Abi = <&'a JsValue as IntoWasmAbi>::Abi;
#[inline]
fn into_abi(self) -> Self::Abi {
(&self.obj).into_abi()
}
}
impl RefFromWasmAbi for JsType {
type Abi = <JsValue as RefFromWasmAbi>::Abi;
type Anchor = core::mem::ManuallyDrop<JsType>;
#[inline]
unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor {
let tmp = <JsValue as RefFromWasmAbi>::ref_from_abi(js);
core::mem::ManuallyDrop::new(JsType {
obj: core::mem::ManuallyDrop::into_inner(tmp).into(),
})
}
}
impl LongRefFromWasmAbi for JsType {
type Abi = <JsValue as LongRefFromWasmAbi>::Abi;
type Anchor = JsType;
#[inline]
unsafe fn long_ref_from_abi(js: Self::Abi) -> Self::Anchor {
let tmp = <JsValue as LongRefFromWasmAbi>::long_ref_from_abi(js);
JsType { obj: tmp.into() }
}
}
impl From<JsValue> for JsType {
#[inline]
fn from(obj: JsValue) -> JsType {
JsType { obj: obj.into() }
}
}
impl AsRef<JsValue> for JsType {
#[inline]
fn as_ref(&self) -> &JsValue {
self.obj.as_ref()
}
}
impl AsRef<JsType> for JsType {
#[inline]
fn as_ref(&self) -> &JsType {
self
}
}
impl From<JsType> for JsValue {
#[inline]
fn from(obj: JsType) -> JsValue {
obj.obj.into()
}
}
impl JsCast for JsType {
fn instanceof(val: &JsValue) -> bool {
#[cfg(
not(
all(
target_arch = "wasm32",
not(any(target_os = "emscripten", target_os = "wasi"))
)
)
)]
unsafe fn __wbg_instanceof_JsType_1641ac20ec916ae7(_: u32) -> u32 {
{
::std::rt::begin_panic(
"cannot check instanceof on non-wasm targets",
);
};
}
unsafe {
let idx = val.into_abi();
__wbg_instanceof_JsType_1641ac20ec916ae7(idx) != 0
}
}
#[inline]
fn unchecked_from_js(val: JsValue) -> Self {
JsType { obj: val.into() }
}
#[inline]
fn unchecked_from_js_ref(val: &JsValue) -> &Self {
unsafe { &*(val as *const JsValue as *const JsType) }
}
}
impl JsObject for JsType {}
};
#[automatically_derived]
impl core::ops::Deref for JsType {
type Target = wasm_bindgen::JsValue;
#[inline]
fn deref(&self) -> &wasm_bindgen::JsValue {
&self.obj
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(typescript_type = "Borrow")]
pub type JsType;
}
impl<'a> Tsify for Borrow<'a> {
type JsType = JsType;
Expand All @@ -179,12 +30,20 @@ const _: () = {
large_number_types_as_bigints: false,
};
}
#[wasm_bindgen(typescript_custom_section)]
const TS_APPEND_CONTENT: &'static str = "export interface Borrow {\n raw: string;\n cow: string;\n}";
impl<'a> WasmDescribe for Borrow<'a> {
#[inline]
fn describe() {
<Self as Tsify>::JsType::describe()
}
}
impl<'a> WasmDescribeVector for Borrow<'a> {
#[inline]
fn describe_vector() {
<Self as Tsify>::JsType::describe_vector()
}
}
impl<'a> IntoWasmAbi for Borrow<'a>
where
Borrow<'a>: _serde::Serialize,
Expand Down Expand Up @@ -267,6 +126,47 @@ const _: () = {
}
}
}
impl<'a> VectorIntoWasmAbi for Borrow<'a>
where
Borrow<'a>: _serde::Serialize,
{
type Abi = <JsType as VectorIntoWasmAbi>::Abi;
#[inline]
fn vector_into_abi(vector: Box<[Self]>) -> Self::Abi {
let values = vector
.iter()
.map(|value| match value.into_js() {
Ok(js) => js.into(),
Err(err) => {
let loc = core::panic::Location::caller();
let msg = {
let res = ::alloc::fmt::format(
format_args!(
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
.file(), loc.line(), loc.column(),
),
);
res
};
{
#[cold]
#[track_caller]
#[inline(never)]
#[rustc_const_panic_str]
#[rustc_do_not_const_check]
const fn panic_cold_display<T: ::core::fmt::Display>(
arg: &T,
) -> ! {
::core::panicking::panic_display(arg)
}
panic_cold_display(&msg);
};
}
})
.collect();
JsValue::vector_into_abi(values)
}
}
impl<'a> FromWasmAbi for Borrow<'a>
where
Self: _serde::de::DeserializeOwned,
Expand Down Expand Up @@ -311,4 +211,23 @@ const _: () = {
SelfOwner(result.unwrap_throw())
}
}
impl<'a> VectorFromWasmAbi for Borrow<'a>
where
Self: _serde::de::DeserializeOwned,
{
type Abi = <JsType as VectorFromWasmAbi>::Abi;
#[inline]
unsafe fn vector_from_abi(js: Self::Abi) -> Box<[Self]> {
JsValue::vector_from_abi(js)
.into_iter()
.map(|value| {
let result = Self::from_js(value);
if let Err(err) = result {
wasm_bindgen::throw_str(err.to_string().as_ref());
}
result.unwrap_throw()
})
.collect()
}
}
};
Loading
Loading