Skip to content

Commit 646d3b4

Browse files
authored
feat(rust): Expose merge_structurally_equal_types (#1633)
The generate! macro now exposes `merge_structurally_equal_types`. This functionality was previously only available via the `--merge-structurally-equal-types` CLI flag. The underlying functionality is unchanged. Signed-off-by: Scott Andrews <scott@andrews.me>
1 parent a2a1e02 commit 646d3b4

3 files changed

Lines changed: 84 additions & 0 deletions

File tree

crates/guest-rust/macro/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ impl Parse for Config {
168168
Opt::EnableMethodChaining(enable) => {
169169
opts.enable_method_chaining = enable.value();
170170
}
171+
Opt::MergeStructurallyEqualTypes(enable) => {
172+
opts.merge_structurally_equal_types = Some(Some(enable.value()))
173+
}
171174
}
172175
}
173176
} else {
@@ -322,6 +325,7 @@ mod kw {
322325
syn::custom_keyword!(imports);
323326
syn::custom_keyword!(debug);
324327
syn::custom_keyword!(enable_method_chaining);
328+
syn::custom_keyword!(merge_structurally_equal_types);
325329
}
326330

327331
#[derive(Clone)]
@@ -403,6 +407,7 @@ enum Opt {
403407
Async(AsyncFilterSet, Span),
404408
Debug(syn::LitBool),
405409
EnableMethodChaining(syn::LitBool),
410+
MergeStructurallyEqualTypes(syn::LitBool),
406411
}
407412

408413
impl Parse for Opt {
@@ -586,6 +591,10 @@ impl Parse for Opt {
586591
}
587592
Ok(Opt::Async(set, span))
588593
}
594+
} else if l.peek(kw::merge_structurally_equal_types) {
595+
input.parse::<kw::merge_structurally_equal_types>()?;
596+
input.parse::<Token![:]>()?;
597+
Ok(Opt::MergeStructurallyEqualTypes(input.parse()?))
589598
} else {
590599
Err(l.error())
591600
}

crates/guest-rust/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,15 @@ extern crate std;
865865
/// // returning `-> &Self`, to permit method chaining (e.g. for builder).
866866
/// // This expectation is also imposed on exports.
867867
/// enable_method_chaining: true,
868+
///
869+
/// // Find all structurally equal types and only generate one type
870+
/// // definition for each equivalence class.
871+
/// //
872+
/// // Other types in the same class will be type aliases to the generated
873+
/// // type. This avoids clone when converting between types that are
874+
/// // structurally equal, which is useful when import and export the same
875+
/// // interface.
876+
/// merge_structurally_equal_types: true,
868877
/// });
869878
/// ```
870879
///

crates/rust/tests/codegen.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,69 @@ mod method_chaining {
235235
enable_method_chaining: true
236236
});
237237
}
238+
239+
#[allow(unused, reason = "testing codegen, not functionality")]
240+
mod merge_structurally_equal_types {
241+
wit_bindgen::generate!({
242+
inline: r#"
243+
package test:merge-structurally-equal-types;
244+
245+
interface blag {
246+
variant kind1 { a, b(u64), c }
247+
variant kind2 { a, b(u64), c }
248+
record kind3 { a: input-stream }
249+
record kind4 { a: input-stream }
250+
record tree { l: t1, r: t1 }
251+
record t1 { l: t2, r: t2 }
252+
record t2 { l: t3, r: t3 }
253+
record t3 { l: kind1, r: kind2 }
254+
record t-stream { tree: tree, %stream: option<borrow<input-stream>> }
255+
resource input-stream {
256+
read: func(len: u64) -> list<u8>;
257+
}
258+
f: func(x: kind1) -> kind2;
259+
g: func(x: kind3) -> kind4;
260+
h: func(x: t-stream) -> tree;
261+
}
262+
263+
interface blah {
264+
use blag.{input-stream, kind4, t-stream};
265+
variant kind5 { a, b(u64), c }
266+
variant kind6 { a, c, b(u64) }
267+
record kind7 { a: borrow<input-stream> }
268+
record tt { l: t2, r: t2 }
269+
record t1 { l: t3, r: t3 }
270+
record t2 { l: t1, r: t1 }
271+
record t3 { l: kind5, r: kind5 }
272+
variant custom-result { ok(tt), err }
273+
f: func(x: kind6) -> kind5;
274+
g: func(x: kind7) -> kind4;
275+
h: func(x: t-stream) -> custom-result;
276+
277+
record r1 { a: u8 }
278+
type a1 = u8;
279+
record r2 { a: a1 }
280+
alias-type: func(x: r1) -> r2;
281+
}
282+
283+
interface resources {
284+
resource r1;
285+
type r2 = r1;
286+
287+
record t1 { a: r1 }
288+
record t2 { a: r2 }
289+
alias-own: func(x: t1) -> t2;
290+
alias-aggregate: func(x: option<t1>) -> option<t2>;
291+
}
292+
293+
world proxy {
294+
import blag;
295+
export blag;
296+
import blah;
297+
export blah;
298+
}
299+
"#,
300+
generate_all,
301+
merge_structurally_equal_types: true
302+
});
303+
}

0 commit comments

Comments
 (0)