@@ -29,48 +29,54 @@ pub trait RustGenerator<'a> {
29
29
fn ownership ( & self ) -> Ownership ;
30
30
31
31
fn print_ty ( & mut self , ty : & Type , mode : TypeMode ) {
32
+ self . push_str ( & self . ty ( ty, mode) )
33
+ }
34
+ fn ty ( & self , ty : & Type , mode : TypeMode ) -> String {
32
35
match ty {
33
- Type :: Id ( t) => self . print_tyid ( * t, mode) ,
34
- Type :: Bool => self . push_str ( "bool" ) ,
35
- Type :: U8 => self . push_str ( "u8" ) ,
36
- Type :: U16 => self . push_str ( "u16" ) ,
37
- Type :: U32 => self . push_str ( "u32" ) ,
38
- Type :: U64 => self . push_str ( "u64" ) ,
39
- Type :: S8 => self . push_str ( "i8" ) ,
40
- Type :: S16 => self . push_str ( "i16" ) ,
41
- Type :: S32 => self . push_str ( "i32" ) ,
42
- Type :: S64 => self . push_str ( "i64" ) ,
43
- Type :: F32 => self . push_str ( "f32" ) ,
44
- Type :: F64 => self . push_str ( "f64" ) ,
45
- Type :: Char => self . push_str ( "char" ) ,
36
+ Type :: Id ( t) => self . tyid ( * t, mode) ,
37
+ Type :: Bool => "bool" . to_string ( ) ,
38
+ Type :: U8 => "u8" . to_string ( ) ,
39
+ Type :: U16 => "u16" . to_string ( ) ,
40
+ Type :: U32 => "u32" . to_string ( ) ,
41
+ Type :: U64 => "u64" . to_string ( ) ,
42
+ Type :: S8 => "i8" . to_string ( ) ,
43
+ Type :: S16 => "i16" . to_string ( ) ,
44
+ Type :: S32 => "i32" . to_string ( ) ,
45
+ Type :: S64 => "i64" . to_string ( ) ,
46
+ Type :: F32 => "f32" . to_string ( ) ,
47
+ Type :: F64 => "f64" . to_string ( ) ,
48
+ Type :: Char => "char" . to_string ( ) ,
46
49
Type :: String => match mode {
47
50
TypeMode :: AllBorrowed ( lt) => {
48
- self . push_str ( "&" ) ;
49
51
if lt != "'_" {
50
- self . push_str ( lt) ;
51
- self . push_str ( " " ) ;
52
+ format ! ( "&{lt} str" )
53
+ } else {
54
+ format ! ( "&str" )
52
55
}
53
- self . push_str ( "str" ) ;
54
56
}
55
57
TypeMode :: Owned => {
56
58
let wt = self . wasmtime_path ( ) ;
57
- self . push_str ( & format ! ( "{wt}::component::__internal::String" ) )
59
+ format ! ( "{wt}::component::__internal::String" )
58
60
}
59
61
} ,
60
62
Type :: ErrorContext => {
61
- self . push_str ( "wasmtime::component::ErrorContext" ) ;
63
+ let wt = self . wasmtime_path ( ) ;
64
+ format ! ( "{wt}::component::ErrorContext" )
62
65
}
63
66
}
64
67
}
65
68
66
69
fn print_optional_ty ( & mut self , ty : Option < & Type > , mode : TypeMode ) {
70
+ self . push_str ( & self . optional_ty ( ty, mode) )
71
+ }
72
+ fn optional_ty ( & self , ty : Option < & Type > , mode : TypeMode ) -> String {
67
73
match ty {
68
- Some ( ty) => self . print_ty ( ty, mode) ,
69
- None => self . push_str ( "()" ) ,
74
+ Some ( ty) => self . ty ( ty, mode) ,
75
+ None => "()" . to_string ( ) ,
70
76
}
71
77
}
72
78
73
- fn print_tyid ( & mut self , id : TypeId , mode : TypeMode ) {
79
+ fn tyid ( & self , id : TypeId , mode : TypeMode ) -> String {
74
80
let info = self . info ( id) ;
75
81
let lt = self . lifetime_for ( & info, mode) ;
76
82
let ty = & self . resolve ( ) . types [ id] ;
@@ -80,12 +86,13 @@ pub trait RustGenerator<'a> {
80
86
// context and don't want ownership of the type but we're using an
81
87
// owned type definition. Inject a `&` in front to indicate that, at
82
88
// the API level, ownership isn't required.
89
+ let mut out = String :: new ( ) ;
83
90
if info. has_list && lt. is_none ( ) {
84
91
if let TypeMode :: AllBorrowed ( lt) = mode {
85
- self . push_str ( "&" ) ;
86
92
if lt != "'_" {
87
- self . push_str ( lt) ;
88
- self . push_str ( " " ) ;
93
+ out. push_str ( & format ! ( "&{lt} " ) )
94
+ } else {
95
+ out. push_str ( "&" )
89
96
}
90
97
}
91
98
}
@@ -94,16 +101,16 @@ pub trait RustGenerator<'a> {
94
101
} else {
95
102
self . result_name ( id)
96
103
} ;
97
- self . print_type_name_in_interface ( ty. owner , & name) ;
104
+ out . push_str ( & self . type_name_in_interface ( ty. owner , & name) ) ;
98
105
99
106
// If the type recursively owns data and it's a
100
107
// variant/record/list, then we need to place the
101
108
// lifetime parameter on the type as well.
102
109
if info. has_list && needs_generics ( self . resolve ( ) , & ty. kind ) {
103
- self . print_generics ( lt) ;
110
+ out . push_str ( & self . generics ( lt) ) ;
104
111
}
105
112
106
- return ;
113
+ return out ;
107
114
108
115
fn needs_generics ( resolve : & Resolve , ty : & TypeDefKind ) -> bool {
109
116
match ty {
@@ -130,20 +137,16 @@ pub trait RustGenerator<'a> {
130
137
}
131
138
132
139
match & ty. kind {
133
- TypeDefKind :: List ( t) => self . print_list ( t, mode) ,
140
+ TypeDefKind :: List ( t) => self . list ( t, mode) ,
134
141
135
142
TypeDefKind :: Option ( t) => {
136
- self . push_str ( "Option<" ) ;
137
- self . print_ty ( t, mode) ;
138
- self . push_str ( ">" ) ;
143
+ format ! ( "Option<{}>" , self . ty( t, mode) )
139
144
}
140
145
141
146
TypeDefKind :: Result ( r) => {
142
- self . push_str ( "Result<" ) ;
143
- self . print_optional_ty ( r. ok . as_ref ( ) , mode) ;
144
- self . push_str ( "," ) ;
145
- self . print_optional_ty ( r. err . as_ref ( ) , mode) ;
146
- self . push_str ( ">" ) ;
147
+ let ok = self . optional_ty ( r. ok . as_ref ( ) , mode) ;
148
+ let err = self . optional_ty ( r. err . as_ref ( ) , mode) ;
149
+ format ! ( "Result<{ok},{err}>" )
147
150
}
148
151
149
152
TypeDefKind :: Variant ( _) => panic ! ( "unsupported anonymous variant" ) ,
@@ -152,12 +155,13 @@ pub trait RustGenerator<'a> {
152
155
// types. Note the trailing comma after each member to
153
156
// appropriately handle 1-tuples.
154
157
TypeDefKind :: Tuple ( t) => {
155
- self . push_str ( "(" ) ;
158
+ let mut out = "(" . to_string ( ) ;
156
159
for ty in t. types . iter ( ) {
157
- self . print_ty ( ty, mode) ;
158
- self . push_str ( "," ) ;
160
+ out . push_str ( & self . ty ( ty, mode) ) ;
161
+ out . push_str ( "," ) ;
159
162
}
160
- self . push_str ( ")" ) ;
163
+ out. push_str ( ")" ) ;
164
+ out
161
165
}
162
166
TypeDefKind :: Record ( _) => {
163
167
panic ! ( "unsupported anonymous type reference: record" )
@@ -169,76 +173,86 @@ pub trait RustGenerator<'a> {
169
173
panic ! ( "unsupported anonymous type reference: enum" )
170
174
}
171
175
TypeDefKind :: Future ( ty) => {
172
- self . push_str ( "wasmtime::component::FutureReader<" ) ;
173
- self . print_optional_ty ( ty. as_ref ( ) , TypeMode :: Owned ) ;
174
- self . push_str ( " >") ;
176
+ let wt = self . wasmtime_path ( ) ;
177
+ let t = self . optional_ty ( ty. as_ref ( ) , TypeMode :: Owned ) ;
178
+ format ! ( "{wt}::component::FutureReader<{t} >")
175
179
}
176
180
TypeDefKind :: Stream ( ty) => {
177
- self . push_str ( "wasmtime::component::StreamReader<" ) ;
178
- self . print_optional_ty ( ty. as_ref ( ) , TypeMode :: Owned ) ;
179
- self . push_str ( ">" ) ;
180
- }
181
- TypeDefKind :: Handle ( handle) => {
182
- self . print_handle ( handle) ;
181
+ let wt = self . wasmtime_path ( ) ;
182
+ let t = self . optional_ty ( ty. as_ref ( ) , TypeMode :: Owned ) ;
183
+ format ! ( "{wt}::component::StreamReader<{t}>" )
183
184
}
185
+ TypeDefKind :: Handle ( handle) => self . handle ( handle) ,
184
186
TypeDefKind :: Resource => unreachable ! ( ) ,
185
187
186
- TypeDefKind :: Type ( t) => self . print_ty ( t, mode) ,
188
+ TypeDefKind :: Type ( t) => self . ty ( t, mode) ,
187
189
TypeDefKind :: Unknown => unreachable ! ( ) ,
188
190
}
189
191
}
190
192
191
- fn print_type_name_in_interface ( & mut self , owner : TypeOwner , name : & str ) {
193
+ fn type_name_in_interface ( & self , owner : TypeOwner , name : & str ) -> String {
194
+ let mut out = String :: new ( ) ;
192
195
if let TypeOwner :: Interface ( id) = owner {
193
196
if let Some ( path) = self . path_to_interface ( id) {
194
- self . push_str ( & path) ;
195
- self . push_str ( "::" ) ;
197
+ out . push_str ( & path) ;
198
+ out . push_str ( "::" ) ;
196
199
}
197
200
}
198
- self . push_str ( name) ;
201
+ out. push_str ( name) ;
202
+ out
199
203
}
200
204
201
205
fn print_list ( & mut self , ty : & Type , mode : TypeMode ) {
206
+ self . push_str ( & self . list ( ty, mode) )
207
+ }
208
+ fn list ( & self , ty : & Type , mode : TypeMode ) -> String {
202
209
let next_mode = if matches ! ( self . ownership( ) , Ownership :: Owning ) {
203
210
TypeMode :: Owned
204
211
} else {
205
212
mode
206
213
} ;
214
+ let ty = self . ty ( ty, next_mode) ;
207
215
match mode {
208
216
TypeMode :: AllBorrowed ( lt) => {
209
- self . push_str ( "&" ) ;
210
217
if lt != "'_" {
211
- self . push_str ( lt) ;
212
- self . push_str ( " " ) ;
218
+ format ! ( "&{lt} [{ty}]" )
219
+ } else {
220
+ format ! ( "&[{ty}]" )
213
221
}
214
- self . push_str ( "[" ) ;
215
- self . print_ty ( ty, next_mode) ;
216
- self . push_str ( "]" ) ;
217
222
}
218
223
TypeMode :: Owned => {
219
224
let wt = self . wasmtime_path ( ) ;
220
- self . push_str ( & format ! ( "{wt}::component::__internal::Vec<" ) ) ;
221
- self . print_ty ( ty, next_mode) ;
222
- self . push_str ( ">" ) ;
225
+ format ! ( "{wt}::component::__internal::Vec<{ty}>" )
223
226
}
224
227
}
225
228
}
226
229
227
230
fn print_stream ( & mut self , ty : Option < & Type > ) {
231
+ self . push_str ( & self . stream ( ty) )
232
+ }
233
+ fn stream ( & self , ty : Option < & Type > ) -> String {
228
234
let wt = self . wasmtime_path ( ) ;
229
- self . push_str ( & format ! ( "{wt}::component::StreamReader<" ) ) ;
230
- self . print_optional_ty ( ty, TypeMode :: Owned ) ;
231
- self . push_str ( ">" ) ;
235
+ let mut out = format ! ( "{wt}::component::StreamReader<" ) ;
236
+ out. push_str ( & self . optional_ty ( ty, TypeMode :: Owned ) ) ;
237
+ out. push_str ( ">" ) ;
238
+ out
232
239
}
233
240
234
241
fn print_future ( & mut self , ty : Option < & Type > ) {
242
+ self . push_str ( & self . future ( ty) )
243
+ }
244
+ fn future ( & self , ty : Option < & Type > ) -> String {
235
245
let wt = self . wasmtime_path ( ) ;
236
- self . push_str ( & format ! ( "{wt}::component::FutureReader<" ) ) ;
237
- self . print_optional_ty ( ty, TypeMode :: Owned ) ;
238
- self . push_str ( ">" ) ;
246
+ let mut out = format ! ( "{wt}::component::FutureReader<" ) ;
247
+ out. push_str ( & self . optional_ty ( ty, TypeMode :: Owned ) ) ;
248
+ out. push_str ( ">" ) ;
249
+ out
239
250
}
240
251
241
252
fn print_handle ( & mut self , handle : & Handle ) {
253
+ self . push_str ( & self . handle ( handle) )
254
+ }
255
+ fn handle ( & self , handle : & Handle ) -> String {
242
256
// Handles are either printed as `ResourceAny` for any guest-defined
243
257
// resource or `Resource<T>` for all host-defined resources. This means
244
258
// that this function needs to determine if `handle` points to a host
@@ -263,27 +277,27 @@ pub trait RustGenerator<'a> {
263
277
} ;
264
278
let wt = self . wasmtime_path ( ) ;
265
279
if is_host_defined {
266
- self . push_str ( & format ! ( "{wt}::component::Resource<" ) ) ;
267
- self . print_type_name_in_interface (
280
+ let mut out = format ! ( "{wt}::component::Resource<" ) ;
281
+ out . push_str ( & self . type_name_in_interface (
268
282
ty. owner ,
269
283
& ty. name . as_ref ( ) . unwrap ( ) . to_upper_camel_case ( ) ,
270
- ) ;
271
- self . push_str ( ">" ) ;
284
+ ) ) ;
285
+ out. push_str ( ">" ) ;
286
+ out
272
287
} else {
273
- self . push_str ( & format ! ( "{wt}::component::ResourceAny" ) ) ;
288
+ format ! ( "{wt}::component::ResourceAny" )
274
289
}
275
290
}
276
291
277
292
fn print_generics ( & mut self , lifetime : Option < & str > ) {
278
- if lifetime. is_none ( ) {
279
- return ;
280
- }
281
- self . push_str ( "<" ) ;
293
+ self . push_str ( & self . generics ( lifetime) )
294
+ }
295
+ fn generics ( & self , lifetime : Option < & str > ) -> String {
282
296
if let Some ( lt) = lifetime {
283
- self . push_str ( lt) ;
284
- self . push_str ( "," ) ;
297
+ format ! ( "<{lt},>" )
298
+ } else {
299
+ String :: new ( )
285
300
}
286
- self . push_str ( ">" ) ;
287
301
}
288
302
289
303
fn modes_of ( & self , ty : TypeId ) -> Vec < ( String , TypeMode ) > {
@@ -377,6 +391,21 @@ pub trait RustGenerator<'a> {
377
391
None
378
392
}
379
393
}
394
+
395
+ fn typedfunc_sig ( & self , func : & Function , param_mode : TypeMode ) -> String {
396
+ let mut out = "(" . to_string ( ) ;
397
+ for ( _, ty) in func. params . iter ( ) {
398
+ out. push_str ( & self . ty ( ty, param_mode) ) ;
399
+ out. push_str ( ", " ) ;
400
+ }
401
+ out. push_str ( "), (" ) ;
402
+ if let Some ( ty) = func. result {
403
+ out. push_str ( & self . ty ( & ty, TypeMode :: Owned ) ) ;
404
+ out. push_str ( ", " ) ;
405
+ }
406
+ out. push_str ( ")" ) ;
407
+ out
408
+ }
380
409
}
381
410
382
411
/// Translate `name` to a Rust `snake_case` identifier.
0 commit comments