Skip to content

Commit 153b870

Browse files
committed
Support custom Rust types for list
Any type that implements `From<Vec<T>>`, `Into<Vec<T>>` and `Deref<Target = Vec<T>>` can be used for a WIT type `list<T>` via the `with` option.
1 parent 2a6d845 commit 153b870

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

crates/rust/src/bindgen.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,10 @@ impl Bindgen for FunctionBindgen<'_, '_> {
674674
self.push_str(&format!("let {} = {};\n", val, operands[0]));
675675
} else {
676676
let op0 = operands.pop().unwrap();
677-
self.push_str(&format!("let {} = ({}).into_boxed_slice();\n", val, op0));
677+
self.push_str(&format!(
678+
"let {} = <_ as Into<Vec<_>>>::into({}).into_boxed_slice();\n",
679+
val, op0
680+
));
678681
}
679682
self.push_str(&format!("let {} = {}.as_ptr().cast::<u8>();\n", ptr, val));
680683
self.push_str(&format!("let {} = {}.len();\n", len, val));
@@ -691,7 +694,7 @@ impl Bindgen for FunctionBindgen<'_, '_> {
691694
self.push_str(&format!("let {} = {};\n", len, operands[1]));
692695
let vec = self.r#gen.path_to_vec();
693696
let result = format!(
694-
"{vec}::from_raw_parts({}.cast(), {1}, {1})",
697+
"<_ as From<Vec<_>>>::from({vec}::from_raw_parts({}.cast(), {1}, {1}))",
695698
operands[0], len
696699
);
697700
results.push(result);

crates/rust/tests/codegen.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,51 @@ mod inline_and_path {
3131
generate_all,
3232
});
3333
}
34+
35+
#[allow(unused)]
36+
mod newtyped_list {
37+
use std::ops::Deref;
38+
39+
wit_bindgen::generate!({
40+
inline: r#"
41+
package test:newtyped-list;
42+
43+
interface ntl {
44+
type newtyped-list = list<u8>;
45+
type typed-list = list<u8>;
46+
}
47+
48+
world test {
49+
use ntl.{newtyped-list, typed-list};
50+
import use-newtyped-list: func(nl: newtyped-list) -> newtyped-list;
51+
import use-typed-list: func(tl: typed-list) -> typed-list;
52+
import use-list: func(l: list<u8>) -> list<u8>;
53+
}
54+
"#,
55+
with: {
56+
"test:newtyped-list/ntl/newtyped-list": NewtypedList,
57+
}
58+
});
59+
60+
struct NewtypedList(Vec<u8>);
61+
62+
impl Deref for NewtypedList {
63+
type Target = Vec<u8>;
64+
65+
fn deref(&self) -> &Self::Target {
66+
&self.0
67+
}
68+
}
69+
70+
impl From<Vec<u8>> for NewtypedList {
71+
fn from(value: Vec<u8>) -> Self {
72+
NewtypedList(value)
73+
}
74+
}
75+
76+
impl From<NewtypedList> for Vec<u8> {
77+
fn from(value: NewtypedList) -> Self {
78+
value.0
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)