1use heck::*;
2use std::collections::HashMap;
3use std::fmt::{self, Write};
4use std::iter::zip;
5use wasmer_wit_bindgen_gen_core::wit_parser::abi::{Bitcast, LiftLower, WasmType};
6use wasmer_wit_bindgen_gen_core::{wit_parser::*, TypeInfo, Types};
7
8#[derive(Debug, Copy, Clone, PartialEq)]
9pub enum TypeMode {
10 Owned,
11 AllBorrowed(&'static str),
12 LeafBorrowed(&'static str),
13 HandlesBorrowed(&'static str),
14}
15
16pub trait RustGenerator {
17 fn push_str(&mut self, s: &str);
18 fn info(&self, ty: TypeId) -> TypeInfo;
19 fn types_mut(&mut self) -> &mut Types;
20 fn print_borrowed_slice(
21 &mut self,
22 iface: &Interface,
23 mutbl: bool,
24 ty: &Type,
25 lifetime: &'static str,
26 );
27 fn print_borrowed_str(&mut self, lifetime: &'static str);
28 fn default_param_mode(&self) -> TypeMode;
29 fn handle_projection(&self) -> Option<(&'static str, String)>;
30 fn handle_wrapper(&self) -> Option<&'static str>;
31 fn handle_in_super(&self) -> bool {
32 false
33 }
34
35 fn rustdoc(&mut self, docs: &Docs) {
36 let docs = match &docs.contents {
37 Some(docs) => docs,
38 None => return,
39 };
40 for line in docs.trim().lines() {
41 self.push_str("/// ");
42 self.push_str(line);
43 self.push_str("\n");
44 }
45 }
46
47 fn rustdoc_params(&mut self, docs: &[(String, Type)], header: &str) {
48 drop((docs, header));
49 }
82
83 fn print_signature(
84 &mut self,
85 iface: &Interface,
86 func: &Function,
87 param_mode: TypeMode,
88 sig: &FnSig,
89 ) -> Vec<String> {
90 let params = self.print_docs_and_params(iface, func, param_mode, &sig);
91 self.push_str(" -> ");
92 self.print_ty(iface, &func.result, TypeMode::Owned);
93 params
94 }
95
96 fn print_docs_and_params(
97 &mut self,
98 iface: &Interface,
99 func: &Function,
100 param_mode: TypeMode,
101 sig: &FnSig,
102 ) -> Vec<String> {
103 self.rustdoc(&func.docs);
104 self.rustdoc_params(&func.params, "Parameters");
105 if !sig.private {
109 self.push_str("pub ");
110 }
111 if sig.unsafe_ {
112 self.push_str("unsafe ");
113 }
114 if sig.async_ {
115 self.push_str("async ");
116 }
117 self.push_str("fn ");
118 let func_name = if sig.use_item_name {
119 func.item_name()
120 } else {
121 &func.name
122 };
123 self.push_str(&to_rust_ident(&func_name));
124 if let Some(generics) = &sig.generics {
125 self.push_str(generics);
126 }
127 self.push_str("(");
128 if let Some(arg) = &sig.self_arg {
129 self.push_str(arg);
130 self.push_str(",");
131 }
132 let mut params = Vec::new();
133 for (i, (name, param)) in func.params.iter().enumerate() {
134 if i == 0 && sig.self_is_first_param {
135 params.push("self".to_string());
136 continue;
137 }
138 let name = to_rust_ident(name);
139 self.push_str(&name);
140 params.push(name);
141 self.push_str(": ");
142 self.print_ty(iface, param, param_mode);
143 self.push_str(",");
144 }
145 self.push_str(")");
146 params
147 }
148
149 fn print_ty(&mut self, iface: &Interface, ty: &Type, mode: TypeMode) {
150 match ty {
151 Type::Id(t) => self.print_tyid(iface, *t, mode),
152 Type::Handle(r) => {
153 let mut info = TypeInfo::default();
154 info.has_handle = true;
155 let lt = self.lifetime_for(&info, mode);
156 if let Some(lt) = lt {
159 self.push_str("&");
160 if lt != "'_" {
161 self.push_str(lt);
162 }
163 self.push_str(" ");
164 }
165
166 let suffix = match self.handle_wrapper() {
167 Some(wrapper) => {
168 self.push_str(wrapper);
169 self.push_str("<");
170 ">"
171 }
172 None => "",
173 };
174 if self.handle_in_super() {
175 self.push_str("super::");
176 }
177 if let Some((proj, _)) = self.handle_projection() {
178 self.push_str(proj);
179 self.push_str("::");
180 }
181 self.push_str(&iface.resources[*r].name.to_camel_case());
182 self.push_str(suffix);
183 }
184
185 Type::Unit => self.push_str("()"),
186 Type::Bool => self.push_str("bool"),
187 Type::U8 => self.push_str("u8"),
188 Type::U16 => self.push_str("u16"),
189 Type::U32 => self.push_str("u32"),
190 Type::U64 => self.push_str("u64"),
191 Type::S8 => self.push_str("i8"),
192 Type::S16 => self.push_str("i16"),
193 Type::S32 => self.push_str("i32"),
194 Type::S64 => self.push_str("i64"),
195 Type::Float32 => self.push_str("f32"),
196 Type::Float64 => self.push_str("f64"),
197 Type::Char => self.push_str("char"),
198 Type::String => match mode {
199 TypeMode::AllBorrowed(lt) | TypeMode::LeafBorrowed(lt) => {
200 self.print_borrowed_str(lt)
201 }
202 TypeMode::Owned | TypeMode::HandlesBorrowed(_) => self.push_str("String"),
203 },
204 }
205 }
206
207 fn print_tyid(&mut self, iface: &Interface, id: TypeId, mode: TypeMode) {
208 let info = self.info(id);
209 let lt = self.lifetime_for(&info, mode);
210 let ty = &iface.types[id];
211 if ty.name.is_some() {
212 let name = if lt.is_some() {
213 self.param_name(iface, id)
214 } else {
215 self.result_name(iface, id)
216 };
217 self.push_str(&name);
218
219 if info.owns_data() && needs_generics(iface, &ty.kind) {
223 self.print_generics(&info, lt, false);
224 }
225
226 return;
227
228 fn needs_generics(iface: &Interface, ty: &TypeDefKind) -> bool {
229 match ty {
230 TypeDefKind::Variant(_)
231 | TypeDefKind::Record(_)
232 | TypeDefKind::Option(_)
233 | TypeDefKind::Expected(_)
234 | TypeDefKind::Future(_)
235 | TypeDefKind::Stream(_)
236 | TypeDefKind::List(_)
237 | TypeDefKind::Flags(_)
238 | TypeDefKind::Enum(_)
239 | TypeDefKind::Tuple(_)
240 | TypeDefKind::Union(_) => true,
241 TypeDefKind::Type(Type::Id(t)) => needs_generics(iface, &iface.types[*t].kind),
242 TypeDefKind::Type(Type::String) => true,
243 TypeDefKind::Type(Type::Handle(_)) => true,
244 TypeDefKind::Type(_) => false,
245 }
246 }
247 }
248
249 match &ty.kind {
250 TypeDefKind::List(t) => self.print_list(iface, t, mode),
251
252 TypeDefKind::Option(t) => {
253 self.push_str("Option<");
254 self.print_ty(iface, t, mode);
255 self.push_str(">");
256 }
257
258 TypeDefKind::Expected(e) => {
259 self.push_str("Result<");
260 self.print_ty(iface, &e.ok, mode);
261 self.push_str(",");
262 self.print_ty(iface, &e.err, mode);
263 self.push_str(">");
264 }
265
266 TypeDefKind::Variant(_) => panic!("unsupported anonymous variant"),
267
268 TypeDefKind::Tuple(t) => {
272 self.push_str("(");
273 for ty in t.types.iter() {
274 self.print_ty(iface, ty, mode);
275 self.push_str(",");
276 }
277 self.push_str(")");
278 }
279 TypeDefKind::Record(_) => {
280 panic!("unsupported anonymous type reference: record")
281 }
282 TypeDefKind::Flags(_) => {
283 panic!("unsupported anonymous type reference: flags")
284 }
285 TypeDefKind::Enum(_) => {
286 panic!("unsupported anonymous type reference: enum")
287 }
288 TypeDefKind::Union(_) => {
289 panic!("unsupported anonymous type reference: union")
290 }
291 TypeDefKind::Future(ty) => {
292 self.push_str("Future<");
293 self.print_ty(iface, ty, mode);
294 self.push_str(">");
295 }
296 TypeDefKind::Stream(stream) => {
297 self.push_str("Stream<");
298 self.print_ty(iface, &stream.element, mode);
299 self.push_str(",");
300 self.print_ty(iface, &stream.end, mode);
301 self.push_str(">");
302 }
303
304 TypeDefKind::Type(t) => self.print_ty(iface, t, mode),
305 }
306 }
307
308 fn print_list(&mut self, iface: &Interface, ty: &Type, mode: TypeMode) {
309 match mode {
310 TypeMode::AllBorrowed(lt) => {
311 self.print_borrowed_slice(iface, false, ty, lt);
312 }
313 TypeMode::LeafBorrowed(lt) => {
314 if iface.all_bits_valid(ty) {
315 self.print_borrowed_slice(iface, false, ty, lt);
316 } else {
317 self.push_str("Vec<");
318 self.print_ty(iface, ty, mode);
319 self.push_str(">");
320 }
321 }
322 TypeMode::HandlesBorrowed(_) | TypeMode::Owned => {
323 self.push_str("Vec<");
324 self.print_ty(iface, ty, mode);
325 self.push_str(">");
326 }
327 }
328 }
329
330 fn print_rust_slice(
331 &mut self,
332 iface: &Interface,
333 mutbl: bool,
334 ty: &Type,
335 lifetime: &'static str,
336 ) {
337 self.push_str("&");
338 if lifetime != "'_" {
339 self.push_str(lifetime);
340 self.push_str(" ");
341 }
342 if mutbl {
343 self.push_str(" mut ");
344 }
345 self.push_str("[");
346 self.print_ty(iface, ty, TypeMode::AllBorrowed(lifetime));
347 self.push_str("]");
348 }
349
350 fn print_generics(&mut self, info: &TypeInfo, lifetime: Option<&str>, bound: bool) {
351 let proj = if info.has_handle {
352 self.handle_projection()
353 } else {
354 None
355 };
356 if lifetime.is_none() && proj.is_none() {
357 return;
358 }
359 self.push_str("<");
360 if let Some(lt) = lifetime {
361 self.push_str(lt);
362 self.push_str(",");
363 }
364 if let Some((proj, trait_bound)) = proj {
365 self.push_str(proj);
366 if bound {
367 self.push_str(": ");
368 self.push_str(&trait_bound);
369 }
370 }
371 self.push_str(">");
372 }
373
374 fn int_repr(&mut self, repr: Int) {
375 self.push_str(int_repr(repr));
376 }
377
378 fn wasm_type(&mut self, ty: WasmType) {
379 self.push_str(wasm_type(ty));
380 }
381
382 fn modes_of(
383 &self,
384 iface: &Interface,
385 ty: TypeId,
386 generate_struct_always: bool,
387 ) -> Vec<(String, TypeMode)> {
388 let info = self.info(ty);
389 let mut result = Vec::new();
390 if info.param || generate_struct_always {
391 result.push((self.param_name(iface, ty), self.default_param_mode()));
392 }
393 if info.result && (!(info.param || generate_struct_always) || self.uses_two_names(&info)) {
394 result.push((self.result_name(iface, ty), TypeMode::Owned));
395 }
396 return result;
397 }
398
399 fn write_name(&self, iface: &Interface, ty: &Type, out: &mut String) {
401 match ty {
402 Type::Unit => out.push_str("Unit"),
403 Type::Bool => out.push_str("Bool"),
404 Type::U8 => out.push_str("U8"),
405 Type::U16 => out.push_str("U16"),
406 Type::U32 => out.push_str("U32"),
407 Type::U64 => out.push_str("U64"),
408 Type::S8 => out.push_str("I8"),
409 Type::S16 => out.push_str("I16"),
410 Type::S32 => out.push_str("I32"),
411 Type::S64 => out.push_str("I64"),
412 Type::Float32 => out.push_str("F32"),
413 Type::Float64 => out.push_str("F64"),
414 Type::Char => out.push_str("Char"),
415 Type::String => out.push_str("String"),
416 Type::Handle(id) => out.push_str(&iface.resources[*id].name.to_camel_case()),
417 Type::Id(id) => {
418 let ty = &iface.types[*id];
419 match &ty.name {
420 Some(name) => out.push_str(&name.to_camel_case()),
421 None => match &ty.kind {
422 TypeDefKind::Option(ty) => {
423 out.push_str("Optional");
424 self.write_name(iface, ty, out);
425 }
426 TypeDefKind::Expected(_) => out.push_str("Result"),
427 TypeDefKind::Tuple(_) => out.push_str("Tuple"),
428 TypeDefKind::List(ty) => {
429 self.write_name(iface, ty, out);
430 out.push_str("List")
431 }
432 TypeDefKind::Future(ty) => {
433 self.write_name(iface, ty, out);
434 out.push_str("Future");
435 }
436 TypeDefKind::Stream(s) => {
437 self.write_name(iface, &s.element, out);
438 self.write_name(iface, &s.end, out);
439 out.push_str("Stream");
440 }
441
442 TypeDefKind::Type(ty) => self.write_name(iface, ty, out),
443 TypeDefKind::Record(_) => out.push_str("Record"),
444 TypeDefKind::Flags(_) => out.push_str("Flags"),
445 TypeDefKind::Variant(_) => out.push_str("Variant"),
446 TypeDefKind::Enum(_) => out.push_str("Enum"),
447 TypeDefKind::Union(_) => out.push_str("Union"),
448 },
449 }
450 }
451 }
452 }
453
454 fn union_case_names(&self, iface: &Interface, union: &Union) -> Vec<String> {
456 enum UsedState<'a> {
457 Once(&'a mut String),
461 Multiple(usize),
465 }
466
467 let mut case_names = vec![String::new(); union.cases.len()];
469 let mut used = HashMap::new();
471 for (case, name) in union.cases.iter().zip(case_names.iter_mut()) {
472 self.write_name(iface, &case.ty, name);
473
474 match used.get_mut(name.as_str()) {
475 None => {
476 used.insert(name.clone(), UsedState::Once(name));
479 }
482 Some(state) => match state {
483 UsedState::Multiple(n) => {
484 write!(name, "{n}").unwrap();
486 *n += 1;
488 }
489 UsedState::Once(first) => {
490 first.push('0');
492 name.push('1');
494 *state = UsedState::Multiple(2);
496 }
497 },
498 }
499 }
500
501 case_names
502 }
503
504 fn print_typedef_record(
505 &mut self,
506 iface: &Interface,
507 id: TypeId,
508 record: &Record,
509 docs: &Docs,
510 generate_structs: bool,
511 ) {
512 let info = self.info(id);
513 for (name, mode) in self.modes_of(iface, id, generate_structs) {
514 let lt = self.lifetime_for(&info, mode);
515 self.rustdoc(docs);
516 if !info.owns_data() {
517 self.push_str("#[repr(C)]\n");
518 self.push_str("#[derive(Copy, Clone)]\n");
519 } else if !info.has_handle {
520 self.push_str("#[derive(Clone)]\n");
521 }
522 self.push_str(&format!("pub struct {}", name));
523 self.print_generics(&info, lt, true);
524 self.push_str(" {\n");
525 for field in record.fields.iter() {
526 self.rustdoc(&field.docs);
527 self.push_str("pub ");
528 self.push_str(&to_rust_ident(&field.name));
529 self.push_str(": ");
530 self.print_ty(iface, &field.ty, mode);
531 self.push_str(",\n");
532 }
533 self.push_str("}\n");
534
535 self.push_str("impl");
536 self.print_generics(&info, lt, true);
537 self.push_str(" core::fmt::Debug for ");
538 self.push_str(&name);
539 self.print_generics(&info, lt, false);
540 self.push_str(" {\n");
541 self.push_str(
542 "fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
543 );
544 self.push_str(&format!("f.debug_struct(\"{}\")", name));
545 for field in record.fields.iter() {
546 self.push_str(&format!(
547 ".field(\"{}\", &self.{})",
548 field.name,
549 to_rust_ident(&field.name)
550 ));
551 }
552 self.push_str(".finish()");
553 self.push_str("}\n");
554 self.push_str("}\n");
555 }
556 }
557
558 fn print_typedef_tuple(
559 &mut self,
560 iface: &Interface,
561 id: TypeId,
562 tuple: &Tuple,
563 docs: &Docs,
564 generate_structs: bool,
565 ) {
566 let info = self.info(id);
567 for (name, mode) in self.modes_of(iface, id, generate_structs) {
568 let lt = self.lifetime_for(&info, mode);
569 self.rustdoc(docs);
570 self.push_str(&format!("pub type {}", name));
571 self.print_generics(&info, lt, true);
572 self.push_str(" = (");
573 for ty in tuple.types.iter() {
574 self.print_ty(iface, ty, mode);
575 self.push_str(",");
576 }
577 self.push_str(");\n");
578 }
579 }
580
581 fn print_typedef_variant(
582 &mut self,
583 iface: &Interface,
584 id: TypeId,
585 variant: &Variant,
586 docs: &Docs,
587 generate_structs: bool,
588 ) where
589 Self: Sized,
590 {
591 self.print_rust_enum(
592 iface,
593 id,
594 variant
595 .cases
596 .iter()
597 .map(|c| (c.name.to_camel_case(), &c.docs, &c.ty)),
598 docs,
599 generate_structs,
600 );
601 }
602
603 fn print_typedef_union(
604 &mut self,
605 iface: &Interface,
606 id: TypeId,
607 union: &Union,
608 docs: &Docs,
609 generate_structs: bool,
610 ) where
611 Self: Sized,
612 {
613 self.print_rust_enum(
614 iface,
615 id,
616 zip(self.union_case_names(iface, union), &union.cases)
617 .map(|(name, case)| (name, &case.docs, &case.ty)),
618 docs,
619 generate_structs,
620 );
621 }
622
623 fn print_rust_enum<'a>(
624 &mut self,
625 iface: &Interface,
626 id: TypeId,
627 cases: impl IntoIterator<Item = (String, &'a Docs, &'a Type)> + Clone,
628 docs: &Docs,
629 generate_structs: bool,
630 ) where
631 Self: Sized,
632 {
633 let info = self.info(id);
634
635 for (name, mode) in self.modes_of(iface, id, generate_structs) {
636 let name = name.to_camel_case();
637 self.rustdoc(docs);
638 let lt = self.lifetime_for(&info, mode);
639 if !info.owns_data() {
640 self.push_str("#[derive(Clone, Copy)]\n");
641 } else if !info.has_handle {
642 self.push_str("#[derive(Clone)]\n");
643 }
644 self.push_str(&format!("pub enum {name}"));
645 self.print_generics(&info, lt, true);
646 self.push_str("{\n");
647 for (case_name, docs, payload) in cases.clone() {
648 self.rustdoc(docs);
649 self.push_str(&case_name);
650 if *payload != Type::Unit {
651 self.push_str("(");
652 self.print_ty(iface, payload, mode);
653 self.push_str(")")
654 }
655 self.push_str(",\n");
656 }
657 self.push_str("}\n");
658
659 self.print_rust_enum_debug(
660 id,
661 mode,
662 &name,
663 cases
664 .clone()
665 .into_iter()
666 .map(|(name, _docs, ty)| (name, ty)),
667 );
668 }
669 }
670
671 fn print_rust_enum_debug<'a>(
672 &mut self,
673 id: TypeId,
674 mode: TypeMode,
675 name: &str,
676 cases: impl IntoIterator<Item = (String, &'a Type)>,
677 ) where
678 Self: Sized,
679 {
680 let info = self.info(id);
681 let lt = self.lifetime_for(&info, mode);
682 self.push_str("impl");
683 self.print_generics(&info, lt, true);
684 self.push_str(" core::fmt::Debug for ");
685 self.push_str(name);
686 self.print_generics(&info, lt, false);
687 self.push_str(" {\n");
688 self.push_str("fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n");
689 self.push_str("match self {\n");
690 for (case_name, payload) in cases {
691 self.push_str(name);
692 self.push_str("::");
693 self.push_str(&case_name);
694 if *payload != Type::Unit {
695 self.push_str("(e)");
696 }
697 self.push_str(" => {\n");
698 self.push_str(&format!("f.debug_tuple(\"{}::{}\")", name, case_name));
699 if *payload != Type::Unit {
700 self.push_str(".field(e)");
701 }
702 self.push_str(".finish()\n");
703 self.push_str("}\n");
704 }
705 self.push_str("}\n");
706 self.push_str("}\n");
707 self.push_str("}\n");
708 }
709
710 fn print_typedef_option(
711 &mut self,
712 iface: &Interface,
713 id: TypeId,
714 payload: &Type,
715 docs: &Docs,
716 generate_structs: bool,
717 ) {
718 let info = self.info(id);
719
720 for (name, mode) in self.modes_of(iface, id, generate_structs) {
721 self.rustdoc(docs);
722 let lt = self.lifetime_for(&info, mode);
723 self.push_str(&format!("pub type {}", name));
724 self.print_generics(&info, lt, true);
725 self.push_str("= Option<");
726 self.print_ty(iface, payload, mode);
727 self.push_str(">;\n");
728 }
729 }
730
731 fn print_typedef_expected(
732 &mut self,
733 iface: &Interface,
734 id: TypeId,
735 expected: &Expected,
736 docs: &Docs,
737 generate_structs: bool,
738 ) {
739 let info = self.info(id);
740
741 for (name, mode) in self.modes_of(iface, id, generate_structs) {
742 self.rustdoc(docs);
743 let lt = self.lifetime_for(&info, mode);
744 self.push_str(&format!("pub type {}", name));
745 self.print_generics(&info, lt, true);
746 self.push_str("= Result<");
747 self.print_ty(iface, &expected.ok, mode);
748 self.push_str(",");
749 self.print_ty(iface, &expected.err, mode);
750 self.push_str(">;\n");
751 }
752 }
753
754 fn print_typedef_enum(
755 &mut self,
756 id: TypeId,
757 name: &str,
758 enum_: &Enum,
759 docs: &Docs,
760 generate_structs: bool,
761 ) where
762 Self: Sized,
763 {
764 let is_error = name.contains("errno");
766
767 let name = name.to_camel_case();
768 self.rustdoc(docs);
769 self.push_str("#[repr(");
770 self.int_repr(enum_.tag());
771 self.push_str(")]\n#[derive(Clone, Copy, PartialEq, Eq)]\n");
772 self.push_str(&format!("pub enum {} {{\n", name.to_camel_case()));
773 for case in enum_.cases.iter() {
774 self.rustdoc(&case.docs);
775 self.push_str(&case.name.to_camel_case());
776 self.push_str(",\n");
777 }
778 self.push_str("}\n");
779
780 if is_error {
783 self.push_str("impl ");
784 self.push_str(&name);
785 self.push_str("{\n");
786
787 self.push_str("pub fn name(&self) -> &'static str {\n");
788 self.push_str("match self {\n");
789 for case in enum_.cases.iter() {
790 self.push_str(&name);
791 self.push_str("::");
792 self.push_str(&case.name.to_camel_case());
793 self.push_str(" => \"");
794 self.push_str(case.name.as_str());
795 self.push_str("\",\n");
796 }
797 self.push_str("}\n");
798 self.push_str("}\n");
799
800 self.push_str("pub fn message(&self) -> &'static str {\n");
801 self.push_str("match self {\n");
802 for case in enum_.cases.iter() {
803 self.push_str(&name);
804 self.push_str("::");
805 self.push_str(&case.name.to_camel_case());
806 self.push_str(" => \"");
807 if let Some(contents) = &case.docs.contents {
808 self.push_str(contents.trim());
809 }
810 self.push_str("\",\n");
811 }
812 self.push_str("}\n");
813 self.push_str("}\n");
814
815 self.push_str("}\n");
816
817 self.push_str("impl core::fmt::Debug for ");
818 self.push_str(&name);
819 self.push_str(
820 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
821 );
822 self.push_str("f.debug_struct(\"");
823 self.push_str(&name);
824 self.push_str("\")\n");
825 self.push_str(".field(\"code\", &(*self as i32))\n");
826 self.push_str(".field(\"name\", &self.name())\n");
827 self.push_str(".field(\"message\", &self.message())\n");
828 self.push_str(".finish()\n");
829 self.push_str("}\n");
830 self.push_str("}\n");
831
832 self.push_str("impl core::fmt::Display for ");
833 self.push_str(&name);
834 self.push_str(
835 "{\nfn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n",
836 );
837 self.push_str("write!(f, \"{} (error {})\", self.name(), *self as i32)");
838 self.push_str("}\n");
839 self.push_str("}\n");
840 self.push_str("\n");
841 self.push_str("impl std::error::Error for ");
842 self.push_str(&name);
843 self.push_str("{}\n");
844 } else {
845 self.print_rust_enum_debug(
846 id,
847 TypeMode::Owned,
848 &name,
849 enum_
850 .cases
851 .iter()
852 .map(|c| (c.name.to_camel_case(), &Type::Unit)),
853 )
854 }
855 }
856
857 fn print_typedef_alias(
858 &mut self,
859 iface: &Interface,
860 id: TypeId,
861 ty: &Type,
862 docs: &Docs,
863 generate_structs: bool,
864 ) {
865 let info = self.info(id);
866 for (name, mode) in self.modes_of(iface, id, generate_structs) {
867 self.rustdoc(docs);
868 self.push_str(&format!("pub type {}", name));
869 let lt = self.lifetime_for(&info, mode);
870 self.print_generics(&info, lt, true);
871 self.push_str(" = ");
872 self.print_ty(iface, ty, mode);
873 self.push_str(";\n");
874 }
875 }
876
877 fn print_type_list(
878 &mut self,
879 iface: &Interface,
880 id: TypeId,
881 ty: &Type,
882 docs: &Docs,
883 generate_structs: bool,
884 ) {
885 let info = self.info(id);
886 for (name, mode) in self.modes_of(iface, id, generate_structs) {
887 let lt = self.lifetime_for(&info, mode);
888 self.rustdoc(docs);
889 self.push_str(&format!("pub type {}", name));
890 self.print_generics(&info, lt, true);
891 self.push_str(" = ");
892 self.print_list(iface, ty, mode);
893 self.push_str(";\n");
894 }
895 }
896
897 fn param_name(&self, iface: &Interface, ty: TypeId) -> String {
898 let info = self.info(ty);
899 let name = iface.types[ty].name.as_ref().unwrap().to_camel_case();
900 if self.uses_two_names(&info) {
901 format!("{}Param", name)
902 } else {
903 name
904 }
905 }
906
907 fn result_name(&self, iface: &Interface, ty: TypeId) -> String {
908 let info = self.info(ty);
909 let name = iface.types[ty].name.as_ref().unwrap().to_camel_case();
910 if self.uses_two_names(&info) {
911 format!("{}Result", name)
912 } else {
913 name
914 }
915 }
916
917 fn uses_two_names(&self, info: &TypeInfo) -> bool {
918 info.owns_data()
919 && info.param
920 && info.result
921 && match self.default_param_mode() {
922 TypeMode::AllBorrowed(_) | TypeMode::LeafBorrowed(_) => true,
923 TypeMode::HandlesBorrowed(_) => info.has_handle,
924 TypeMode::Owned => false,
925 }
926 }
927
928 fn lifetime_for(&self, info: &TypeInfo, mode: TypeMode) -> Option<&'static str> {
929 match mode {
930 TypeMode::AllBorrowed(s) | TypeMode::LeafBorrowed(s)
931 if info.has_list || info.has_handle =>
932 {
933 Some(s)
934 }
935 TypeMode::HandlesBorrowed(s) if info.has_handle => Some(s),
936 _ => None,
937 }
938 }
939}
940
941#[derive(Default)]
942pub struct FnSig {
943 pub async_: bool,
944 pub unsafe_: bool,
945 pub private: bool,
946 pub use_item_name: bool,
947 pub generics: Option<String>,
948 pub self_arg: Option<String>,
949 pub self_is_first_param: bool,
950}
951
952pub trait RustFunctionGenerator {
953 fn push_str(&mut self, s: &str);
954 fn tmp(&mut self) -> usize;
955 fn rust_gen(&self) -> &dyn RustGenerator;
956 fn lift_lower(&self) -> LiftLower;
957
958 fn let_results(&mut self, amt: usize, results: &mut Vec<String>) {
959 match amt {
960 0 => {}
961 1 => {
962 let tmp = self.tmp();
963 let res = format!("result{}", tmp);
964 self.push_str("let ");
965 self.push_str(&res);
966 results.push(res);
967 self.push_str(" = ");
968 }
969 n => {
970 let tmp = self.tmp();
971 self.push_str("let (");
972 for i in 0..n {
973 let arg = format!("result{}_{}", tmp, i);
974 self.push_str(&arg);
975 self.push_str(",");
976 results.push(arg);
977 }
978 self.push_str(") = ");
979 }
980 }
981 }
982
983 fn record_lower(
984 &mut self,
985 iface: &Interface,
986 id: TypeId,
987 record: &Record,
988 operand: &str,
989 results: &mut Vec<String>,
990 ) {
991 let tmp = self.tmp();
992 self.push_str("let ");
993 let name = self.typename_lower(iface, id);
994 self.push_str(&name);
995 self.push_str("{ ");
996 for field in record.fields.iter() {
997 let name = to_rust_ident(&field.name);
998 let arg = format!("{}{}", name, tmp);
999 self.push_str(&name);
1000 self.push_str(":");
1001 self.push_str(&arg);
1002 self.push_str(", ");
1003 results.push(arg);
1004 }
1005 self.push_str("} = ");
1006 self.push_str(operand);
1007 self.push_str(";\n");
1008 }
1009
1010 fn record_lift(
1011 &mut self,
1012 iface: &Interface,
1013 id: TypeId,
1014 ty: &Record,
1015 operands: &[String],
1016 results: &mut Vec<String>,
1017 ) {
1018 let mut result = self.typename_lift(iface, id);
1019 result.push_str("{");
1020 for (field, val) in ty.fields.iter().zip(operands) {
1021 result.push_str(&to_rust_ident(&field.name));
1022 result.push_str(":");
1023 result.push_str(&val);
1024 result.push_str(", ");
1025 }
1026 result.push_str("}");
1027 results.push(result);
1028 }
1029
1030 fn tuple_lower(&mut self, tuple: &Tuple, operand: &str, results: &mut Vec<String>) {
1031 let tmp = self.tmp();
1032 self.push_str("let (");
1033 for i in 0..tuple.types.len() {
1034 let arg = format!("t{}_{}", tmp, i);
1035 self.push_str(&arg);
1036 self.push_str(", ");
1037 results.push(arg);
1038 }
1039 self.push_str(") = ");
1040 self.push_str(operand);
1041 self.push_str(";\n");
1042 }
1043
1044 fn tuple_lift(&mut self, operands: &[String], results: &mut Vec<String>) {
1045 if operands.len() == 1 {
1046 results.push(format!("({},)", operands[0]));
1047 } else {
1048 results.push(format!("({})", operands.join(", ")));
1049 }
1050 }
1051
1052 fn typename_lower(&self, iface: &Interface, id: TypeId) -> String {
1053 match self.lift_lower() {
1054 LiftLower::LowerArgsLiftResults => self.rust_gen().param_name(iface, id),
1055 LiftLower::LiftArgsLowerResults => self.rust_gen().result_name(iface, id),
1056 }
1057 }
1058
1059 fn typename_lift(&self, iface: &Interface, id: TypeId) -> String {
1060 match self.lift_lower() {
1061 LiftLower::LiftArgsLowerResults => self.rust_gen().param_name(iface, id),
1062 LiftLower::LowerArgsLiftResults => self.rust_gen().result_name(iface, id),
1063 }
1064 }
1065}
1066
1067pub fn to_rust_ident(name: &str) -> String {
1068 match name {
1069 "as" => "as_".into(),
1072 "break" => "break_".into(),
1073 "const" => "const_".into(),
1074 "continue" => "continue_".into(),
1075 "crate" => "crate_".into(),
1076 "else" => "else_".into(),
1077 "enum" => "enum_".into(),
1078 "extern" => "extern_".into(),
1079 "false" => "false_".into(),
1080 "fn" => "fn_".into(),
1081 "for" => "for_".into(),
1082 "if" => "if_".into(),
1083 "impl" => "impl_".into(),
1084 "in" => "in_".into(),
1085 "let" => "let_".into(),
1086 "loop" => "loop_".into(),
1087 "match" => "match_".into(),
1088 "mod" => "mod_".into(),
1089 "move" => "move_".into(),
1090 "mut" => "mut_".into(),
1091 "pub" => "pub_".into(),
1092 "ref" => "ref_".into(),
1093 "return" => "return_".into(),
1094 "self" => "self_".into(),
1095 "static" => "static_".into(),
1096 "struct" => "struct_".into(),
1097 "super" => "super_".into(),
1098 "trait" => "trait_".into(),
1099 "true" => "true_".into(),
1100 "type" => "type_".into(),
1101 "unsafe" => "unsafe_".into(),
1102 "use" => "use_".into(),
1103 "where" => "where_".into(),
1104 "while" => "while_".into(),
1105 "async" => "async_".into(),
1106 "await" => "await_".into(),
1107 "dyn" => "dyn_".into(),
1108 "abstract" => "abstract_".into(),
1109 "become" => "become_".into(),
1110 "box" => "box_".into(),
1111 "do" => "do_".into(),
1112 "final" => "final_".into(),
1113 "macro" => "macro_".into(),
1114 "override" => "override_".into(),
1115 "priv" => "priv_".into(),
1116 "typeof" => "typeof_".into(),
1117 "unsized" => "unsized_".into(),
1118 "virtual" => "virtual_".into(),
1119 "yield" => "yield_".into(),
1120 "try" => "try_".into(),
1121 s => s.to_snake_case(),
1122 }
1123}
1124
1125pub fn wasm_type(ty: WasmType) -> &'static str {
1126 match ty {
1127 WasmType::I32 => "i32",
1128 WasmType::I64 => "i64",
1129 WasmType::F32 => "f32",
1130 WasmType::F64 => "f64",
1131 }
1132}
1133
1134pub fn int_repr(repr: Int) -> &'static str {
1135 match repr {
1136 Int::U8 => "u8",
1137 Int::U16 => "u16",
1138 Int::U32 => "u32",
1139 Int::U64 => "u64",
1140 }
1141}
1142
1143trait TypeInfoExt {
1144 fn owns_data(&self) -> bool;
1145}
1146
1147impl TypeInfoExt for TypeInfo {
1148 fn owns_data(&self) -> bool {
1149 self.has_list || self.has_handle
1150 }
1151}
1152
1153pub fn bitcast(casts: &[Bitcast], operands: &[String], results: &mut Vec<String>) {
1154 for (cast, operand) in casts.iter().zip(operands) {
1155 results.push(match cast {
1156 Bitcast::None => operand.clone(),
1157 Bitcast::I32ToI64 => format!("i64::from({})", operand),
1158 Bitcast::F32ToI32 => format!("({}).to_bits() as i32", operand),
1159 Bitcast::F64ToI64 => format!("({}).to_bits() as i64", operand),
1160 Bitcast::I64ToI32 => format!("{} as i32", operand),
1161 Bitcast::I32ToF32 => format!("f32::from_bits({} as u32)", operand),
1162 Bitcast::I64ToF64 => format!("f64::from_bits({} as u64)", operand),
1163 Bitcast::F32ToI64 => format!("i64::from(({}).to_bits())", operand),
1164 Bitcast::I64ToF32 => format!("f32::from_bits({} as u32)", operand),
1165 });
1166 }
1167}
1168
1169pub enum RustFlagsRepr {
1170 U8,
1171 U16,
1172 U32,
1173 U64,
1174 U128,
1175}
1176
1177impl RustFlagsRepr {
1178 pub fn new(f: &Flags) -> RustFlagsRepr {
1179 match f.repr() {
1180 FlagsRepr::U8 => RustFlagsRepr::U8,
1181 FlagsRepr::U16 => RustFlagsRepr::U16,
1182 FlagsRepr::U32(1) => RustFlagsRepr::U32,
1183 FlagsRepr::U32(2) => RustFlagsRepr::U64,
1184 FlagsRepr::U32(3 | 4) => RustFlagsRepr::U128,
1185 FlagsRepr::U32(n) => panic!("unsupported number of flags: {}", n * 32),
1186 }
1187 }
1188}
1189
1190impl fmt::Display for RustFlagsRepr {
1191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1192 match self {
1193 RustFlagsRepr::U8 => "u8".fmt(f),
1194 RustFlagsRepr::U16 => "u16".fmt(f),
1195 RustFlagsRepr::U32 => "u32".fmt(f),
1196 RustFlagsRepr::U64 => "u64".fmt(f),
1197 RustFlagsRepr::U128 => "u128".fmt(f),
1198 }
1199 }
1200}