Skip to content

Commit 9277dd5

Browse files
authored
Added support for VectorIntoWasmAbi and VectorFromWasmAbi (#41)
Added vector support for using tsify to export types and auto-generate bindings for vectors of structs.
1 parent 2492b09 commit 9277dd5

File tree

12 files changed

+494
-665
lines changed

12 files changed

+494
-665
lines changed

Cargo.toml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ categories = ["wasm"]
1616
[dependencies]
1717
tsify-next-macros = { path = "tsify-next-macros", version = "0.5.3" }
1818
wasm-bindgen = { version = "0.2.86", optional = true }
19-
serde = { version = "1.0", optional = true }
19+
serde = { version = "1.0", features = ["derive"], optional = true }
2020
serde_json = { version = "1.0", optional = true }
2121
serde-wasm-bindgen = { version = "0.6", optional = true }
2222
gloo-utils = { version = "0.2", optional = true }
@@ -26,10 +26,6 @@ indoc = "2.0.5"
2626
js-sys = "0.3"
2727
macrotest = "1.0"
2828
pretty_assertions = "1.4.0"
29-
serde = { version = "1.0", features = ["derive"] }
30-
serde-wasm-bindgen = "0.6"
31-
serde_json = "1.0"
32-
wasm-bindgen = "0.2"
3329
wasm-bindgen-test = "0.3"
3430

3531
[features]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* tslint:disable */
2+
/* eslint-disable */
3+
/**
4+
* @param {Point} point
5+
*/
6+
export function consume(point: Point): void;
7+
/**
8+
* @returns {Point}
9+
*/
10+
export function into_js(): Point;
11+
/**
12+
* @param {(Point)[]} points
13+
*/
14+
export function consume_vector(points: (Point)[]): void;
15+
/**
16+
* @returns {(Point)[]}
17+
*/
18+
export function vector_into_js(): (Point)[];
19+
export interface Point {
20+
x: number;
21+
y: number;
22+
}
23+

tests-e2e/test4/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "test4"
3+
publish = false
4+
version = "0.1.0"
5+
edition = "2021"
6+
7+
[dependencies]
8+
wasm-bindgen = "0.2"
9+
tsify-next = { path = "../..", version = "*" }
10+
serde = { version = "1.0", features = ["derive"] }
11+
serde_json = "1.0"
12+
13+
[dev-dependencies]
14+
wasm-bindgen-test = "0.3"
15+
16+
[lib]
17+
path = "entry_point.rs"
18+
crate-type = ["cdylib"]
19+
20+
[build-dependencies]
21+
wasm-bindgen-cli = "0.2"

tests-e2e/test4/entry_point.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use serde::{Deserialize, Serialize};
2+
use tsify_next::Tsify;
3+
use wasm_bindgen::prelude::*;
4+
5+
#[derive(Tsify, Serialize, Deserialize)]
6+
#[tsify(into_wasm_abi, from_wasm_abi)]
7+
pub struct Point {
8+
x: i32,
9+
y: i32,
10+
}
11+
12+
#[wasm_bindgen]
13+
pub fn consume(point: Point) {}
14+
15+
#[wasm_bindgen]
16+
pub fn into_js() -> Point {
17+
Point { x: 0, y: 0 }
18+
}
19+
20+
#[wasm_bindgen]
21+
pub fn consume_vector(points: Vec<Point>) {}
22+
23+
#[wasm_bindgen]
24+
pub fn vector_into_js() -> Vec<Point> {
25+
vec![
26+
Point { x: 1, y: 6 },
27+
Point { x: 2, y: 5 },
28+
Point { x: 3, y: 4 },
29+
]
30+
}

tests/expand/borrow.expanded.rs

Lines changed: 75 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -11,164 +11,15 @@ const _: () = {
1111
use tsify_next::Tsify;
1212
use wasm_bindgen::{
1313
convert::{
14-
FromWasmAbi, IntoWasmAbi, OptionFromWasmAbi, OptionIntoWasmAbi,
15-
RefFromWasmAbi,
14+
FromWasmAbi, VectorFromWasmAbi, IntoWasmAbi, VectorIntoWasmAbi,
15+
OptionFromWasmAbi, OptionIntoWasmAbi, RefFromWasmAbi,
1616
},
17-
describe::WasmDescribe, prelude::*,
17+
describe::WasmDescribe, describe::WasmDescribeVector, prelude::*,
1818
};
19-
#[automatically_derived]
20-
///
21-
#[repr(transparent)]
22-
pub struct JsType {
23-
obj: wasm_bindgen::JsValue,
24-
}
25-
#[automatically_derived]
26-
const _: () = {
27-
use wasm_bindgen::convert::TryFromJsValue;
28-
use wasm_bindgen::convert::{IntoWasmAbi, FromWasmAbi};
29-
use wasm_bindgen::convert::{OptionIntoWasmAbi, OptionFromWasmAbi};
30-
use wasm_bindgen::convert::{RefFromWasmAbi, LongRefFromWasmAbi};
31-
use wasm_bindgen::describe::WasmDescribe;
32-
use wasm_bindgen::{JsValue, JsCast, JsObject};
33-
use wasm_bindgen::__rt::core;
34-
impl WasmDescribe for JsType {
35-
fn describe() {
36-
use wasm_bindgen::describe::*;
37-
inform(NAMED_EXTERNREF);
38-
inform(6u32);
39-
inform(66u32);
40-
inform(111u32);
41-
inform(114u32);
42-
inform(114u32);
43-
inform(111u32);
44-
inform(119u32);
45-
}
46-
}
47-
impl IntoWasmAbi for JsType {
48-
type Abi = <JsValue as IntoWasmAbi>::Abi;
49-
#[inline]
50-
fn into_abi(self) -> Self::Abi {
51-
self.obj.into_abi()
52-
}
53-
}
54-
impl OptionIntoWasmAbi for JsType {
55-
#[inline]
56-
fn none() -> Self::Abi {
57-
0
58-
}
59-
}
60-
impl<'a> OptionIntoWasmAbi for &'a JsType {
61-
#[inline]
62-
fn none() -> Self::Abi {
63-
0
64-
}
65-
}
66-
impl FromWasmAbi for JsType {
67-
type Abi = <JsValue as FromWasmAbi>::Abi;
68-
#[inline]
69-
unsafe fn from_abi(js: Self::Abi) -> Self {
70-
JsType {
71-
obj: JsValue::from_abi(js).into(),
72-
}
73-
}
74-
}
75-
impl OptionFromWasmAbi for JsType {
76-
#[inline]
77-
fn is_none(abi: &Self::Abi) -> bool {
78-
*abi == 0
79-
}
80-
}
81-
impl<'a> IntoWasmAbi for &'a JsType {
82-
type Abi = <&'a JsValue as IntoWasmAbi>::Abi;
83-
#[inline]
84-
fn into_abi(self) -> Self::Abi {
85-
(&self.obj).into_abi()
86-
}
87-
}
88-
impl RefFromWasmAbi for JsType {
89-
type Abi = <JsValue as RefFromWasmAbi>::Abi;
90-
type Anchor = core::mem::ManuallyDrop<JsType>;
91-
#[inline]
92-
unsafe fn ref_from_abi(js: Self::Abi) -> Self::Anchor {
93-
let tmp = <JsValue as RefFromWasmAbi>::ref_from_abi(js);
94-
core::mem::ManuallyDrop::new(JsType {
95-
obj: core::mem::ManuallyDrop::into_inner(tmp).into(),
96-
})
97-
}
98-
}
99-
impl LongRefFromWasmAbi for JsType {
100-
type Abi = <JsValue as LongRefFromWasmAbi>::Abi;
101-
type Anchor = JsType;
102-
#[inline]
103-
unsafe fn long_ref_from_abi(js: Self::Abi) -> Self::Anchor {
104-
let tmp = <JsValue as LongRefFromWasmAbi>::long_ref_from_abi(js);
105-
JsType { obj: tmp.into() }
106-
}
107-
}
108-
impl From<JsValue> for JsType {
109-
#[inline]
110-
fn from(obj: JsValue) -> JsType {
111-
JsType { obj: obj.into() }
112-
}
113-
}
114-
impl AsRef<JsValue> for JsType {
115-
#[inline]
116-
fn as_ref(&self) -> &JsValue {
117-
self.obj.as_ref()
118-
}
119-
}
120-
impl AsRef<JsType> for JsType {
121-
#[inline]
122-
fn as_ref(&self) -> &JsType {
123-
self
124-
}
125-
}
126-
impl From<JsType> for JsValue {
127-
#[inline]
128-
fn from(obj: JsType) -> JsValue {
129-
obj.obj.into()
130-
}
131-
}
132-
impl JsCast for JsType {
133-
fn instanceof(val: &JsValue) -> bool {
134-
#[cfg(
135-
not(
136-
all(
137-
target_arch = "wasm32",
138-
not(any(target_os = "emscripten", target_os = "wasi"))
139-
)
140-
)
141-
)]
142-
unsafe fn __wbg_instanceof_JsType_1641ac20ec916ae7(_: u32) -> u32 {
143-
{
144-
::std::rt::begin_panic(
145-
"cannot check instanceof on non-wasm targets",
146-
);
147-
};
148-
}
149-
unsafe {
150-
let idx = val.into_abi();
151-
__wbg_instanceof_JsType_1641ac20ec916ae7(idx) != 0
152-
}
153-
}
154-
#[inline]
155-
fn unchecked_from_js(val: JsValue) -> Self {
156-
JsType { obj: val.into() }
157-
}
158-
#[inline]
159-
fn unchecked_from_js_ref(val: &JsValue) -> &Self {
160-
unsafe { &*(val as *const JsValue as *const JsType) }
161-
}
162-
}
163-
impl JsObject for JsType {}
164-
};
165-
#[automatically_derived]
166-
impl core::ops::Deref for JsType {
167-
type Target = wasm_bindgen::JsValue;
168-
#[inline]
169-
fn deref(&self) -> &wasm_bindgen::JsValue {
170-
&self.obj
171-
}
19+
#[wasm_bindgen]
20+
extern "C" {
21+
#[wasm_bindgen(typescript_type = "Borrow")]
22+
pub type JsType;
17223
}
17324
impl<'a> Tsify for Borrow<'a> {
17425
type JsType = JsType;
@@ -179,12 +30,20 @@ const _: () = {
17930
large_number_types_as_bigints: false,
18031
};
18132
}
33+
#[wasm_bindgen(typescript_custom_section)]
34+
const TS_APPEND_CONTENT: &'static str = "export interface Borrow {\n raw: string;\n cow: string;\n}";
18235
impl<'a> WasmDescribe for Borrow<'a> {
18336
#[inline]
18437
fn describe() {
18538
<Self as Tsify>::JsType::describe()
18639
}
18740
}
41+
impl<'a> WasmDescribeVector for Borrow<'a> {
42+
#[inline]
43+
fn describe_vector() {
44+
<Self as Tsify>::JsType::describe_vector()
45+
}
46+
}
18847
impl<'a> IntoWasmAbi for Borrow<'a>
18948
where
19049
Borrow<'a>: _serde::Serialize,
@@ -267,6 +126,47 @@ const _: () = {
267126
}
268127
}
269128
}
129+
impl<'a> VectorIntoWasmAbi for Borrow<'a>
130+
where
131+
Borrow<'a>: _serde::Serialize,
132+
{
133+
type Abi = <JsType as VectorIntoWasmAbi>::Abi;
134+
#[inline]
135+
fn vector_into_abi(vector: Box<[Self]>) -> Self::Abi {
136+
let values = vector
137+
.iter()
138+
.map(|value| match value.into_js() {
139+
Ok(js) => js.into(),
140+
Err(err) => {
141+
let loc = core::panic::Location::caller();
142+
let msg = {
143+
let res = ::alloc::fmt::format(
144+
format_args!(
145+
"(Converting type failed) {0} ({1}:{2}:{3})", err, loc
146+
.file(), loc.line(), loc.column(),
147+
),
148+
);
149+
res
150+
};
151+
{
152+
#[cold]
153+
#[track_caller]
154+
#[inline(never)]
155+
#[rustc_const_panic_str]
156+
#[rustc_do_not_const_check]
157+
const fn panic_cold_display<T: ::core::fmt::Display>(
158+
arg: &T,
159+
) -> ! {
160+
::core::panicking::panic_display(arg)
161+
}
162+
panic_cold_display(&msg);
163+
};
164+
}
165+
})
166+
.collect();
167+
JsValue::vector_into_abi(values)
168+
}
169+
}
270170
impl<'a> FromWasmAbi for Borrow<'a>
271171
where
272172
Self: _serde::de::DeserializeOwned,
@@ -311,4 +211,23 @@ const _: () = {
311211
SelfOwner(result.unwrap_throw())
312212
}
313213
}
214+
impl<'a> VectorFromWasmAbi for Borrow<'a>
215+
where
216+
Self: _serde::de::DeserializeOwned,
217+
{
218+
type Abi = <JsType as VectorFromWasmAbi>::Abi;
219+
#[inline]
220+
unsafe fn vector_from_abi(js: Self::Abi) -> Box<[Self]> {
221+
JsValue::vector_from_abi(js)
222+
.into_iter()
223+
.map(|value| {
224+
let result = Self::from_js(value);
225+
if let Err(err) = result {
226+
wasm_bindgen::throw_str(err.to_string().as_ref());
227+
}
228+
result.unwrap_throw()
229+
})
230+
.collect()
231+
}
232+
}
314233
};

0 commit comments

Comments
 (0)