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