Skip to content

Commit b7c16b9

Browse files
authored
Update traits generated for Rust exports (#651)
* Update traits generated for Rust exports This commit updates the traits generated for Rust exports to be uniformly named `Guest` as opposed to their previous names which were based on the name of the interface or world. This reduces some repetition (e.g. no `foo::Foo`) and additionally enables a nicer fix to the problem of: interface foo { record foo { foo: u32, } } where previously the `struct Foo` generated would clash with `trait Foo`. Now all types named "guest" are renamed to "Guest_" in Rust and the `Guest` name is reserved for the generated trait. This additionally renames resource-related traits to `GuestFoo` in a similar manner to Wasmtime's bindgen using `HostFoo`. Also along the lines of namespacing I've renamed `Rep{Foo}` for resources to just `{Foo}` since the name is now available with the traits being named `Guest{Foo}`. This PR still has conflicts where if you have for example: interface foo { resource foo { } type guest-foo = u32 } that generates an error, but that's getting more niche that I'd prefer to fix that some other time. (Wasmtime's host bindgen has these same issues as well) Closes #650 * Ignore a broken test for java
1 parent d9e460f commit b7c16b9

File tree

23 files changed

+187
-119
lines changed

23 files changed

+187
-119
lines changed

crates/rust-lib/src/lib.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -436,17 +436,16 @@ pub trait RustGenerator<'a> {
436436
}
437437
}
438438
if self.is_exported_resource(*ty) {
439-
self.push_str(&self.type_path_with_name(
440-
*ty,
441-
format!(
442-
"Rep{}",
443-
self.resolve().types[*ty]
444-
.name
445-
.as_deref()
446-
.unwrap()
447-
.to_upper_camel_case()
448-
),
449-
));
439+
self.push_str(
440+
&self.type_path_with_name(
441+
*ty,
442+
self.resolve().types[*ty]
443+
.name
444+
.as_deref()
445+
.unwrap()
446+
.to_upper_camel_case(),
447+
),
448+
);
450449
} else {
451450
self.print_ty(&Type::Id(*ty), mode);
452451
}
@@ -568,7 +567,7 @@ pub trait RustGenerator<'a> {
568567
Type::Id(id) => {
569568
let ty = &self.resolve().types[*id];
570569
match &ty.name {
571-
Some(name) => out.push_str(&name.to_upper_camel_case()),
570+
Some(name) => out.push_str(&to_upper_camel_case(name)),
572571
None => match &ty.kind {
573572
TypeDefKind::Option(ty) => {
574573
out.push_str("Optional");
@@ -836,8 +835,6 @@ pub trait RustGenerator<'a> {
836835
let info = self.info(id);
837836

838837
for (name, mode) in self.modes_of(id) {
839-
let name = name.to_upper_camel_case();
840-
841838
self.rustdoc(docs);
842839
let lt = self.lifetime_for(&info, mode);
843840
if let Some(derive_component) = derive_component {
@@ -995,15 +992,15 @@ pub trait RustGenerator<'a> {
995992
{
996993
let info = self.info(id);
997994

998-
let name = name.to_upper_camel_case();
995+
let name = to_upper_camel_case(name);
999996
self.rustdoc(docs);
1000997
for attr in attrs {
1001998
self.push_str(&format!("{}\n", attr));
1002999
}
10031000
self.push_str("#[repr(");
10041001
self.int_repr(enum_.tag());
10051002
self.push_str(")]\n#[derive(Clone, Copy, PartialEq, Eq)]\n");
1006-
self.push_str(&format!("pub enum {} {{\n", name.to_upper_camel_case()));
1003+
self.push_str(&format!("pub enum {name} {{\n"));
10071004
for case in enum_.cases.iter() {
10081005
self.rustdoc(&case.docs);
10091006
self.push_str(&case_attr(case));
@@ -1101,7 +1098,7 @@ pub trait RustGenerator<'a> {
11011098
// if only borrows are used, no need to generate the `Own{name}`
11021099
// version.
11031100
self.mark_resource_owned(target);
1104-
for prefix in ["Own", "Rep"] {
1101+
for prefix in ["Own", ""] {
11051102
self.rustdoc(docs);
11061103
self.push_str(&format!(
11071104
"pub type {prefix}{} = {};\n",
@@ -1148,11 +1145,7 @@ pub trait RustGenerator<'a> {
11481145

11491146
fn param_name(&self, ty: TypeId) -> String {
11501147
let info = self.info(ty);
1151-
let name = self.resolve().types[ty]
1152-
.name
1153-
.as_ref()
1154-
.unwrap()
1155-
.to_upper_camel_case();
1148+
let name = to_upper_camel_case(self.resolve().types[ty].name.as_ref().unwrap());
11561149
if self.uses_two_names(&info) {
11571150
format!("{}Param", name)
11581151
} else {
@@ -1162,11 +1155,7 @@ pub trait RustGenerator<'a> {
11621155

11631156
fn result_name(&self, ty: TypeId) -> String {
11641157
let info = self.info(ty);
1165-
let name = self.resolve().types[ty]
1166-
.name
1167-
.as_ref()
1168-
.unwrap()
1169-
.to_upper_camel_case();
1158+
let name = to_upper_camel_case(self.resolve().types[ty].name.as_ref().unwrap());
11701159
if self.uses_two_names(&info) {
11711160
format!("{}Result", name)
11721161
} else if self.is_exported_resource(ty) {
@@ -1398,6 +1387,15 @@ pub fn to_rust_ident(name: &str) -> String {
13981387
}
13991388
}
14001389

1390+
pub fn to_upper_camel_case(name: &str) -> String {
1391+
match name {
1392+
// The name "Guest" is reserved for traits generated by exported
1393+
// interfaces, so remap types defined in wit to something else.
1394+
"guest" => "Guest_".to_string(),
1395+
s => s.to_upper_camel_case(),
1396+
}
1397+
}
1398+
14011399
pub fn wasm_type(ty: WasmType) -> &'static str {
14021400
match ty {
14031401
WasmType::I32 => "i32",

0 commit comments

Comments
 (0)