1use heck::*;
2use std::collections::HashMap;
3use std::fmt::{self, Write};
4use std::iter::zip;
5use wai_bindgen_gen_core::wai_parser::abi::{Bitcast, LiftLower, WasmType};
6use wai_bindgen_gen_core::{wai_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 always_generate_structs(&self) -> bool {
38 false
39 }
40
41 fn rustdoc(&mut self, docs: &Docs) {
42 let docs = match &docs.contents {
43 Some(docs) => docs,
44 None => return,
45 };
46 for line in docs.trim().lines() {
47 self.push_str("/// ");
48 self.push_str(line);
49 self.push_str("\n");
50 }
51 }
52
53 fn rustdoc_params(&mut self, docs: &[(String, Type)], header: &str) {
54 drop((docs, header));
55 }
88
89 fn print_signature(
90 &mut self,
91 iface: &Interface,
92 func: &Function,
93 param_mode: TypeMode,
94 sig: &FnSig,
95 ) -> Vec<String> {
96 let params = self.print_docs_and_params(iface, func, param_mode, sig);
97 self.push_str(" -> ");
98 self.print_ty(iface, &func.result, TypeMode::Owned);
99 params
100 }
101
102 fn print_docs_and_params(
103 &mut self,
104 iface: &Interface,
105 func: &Function,
106 param_mode: TypeMode,
107 sig: &FnSig,
108 ) -> Vec<String> {
109 self.rustdoc(&func.docs);
110 self.rustdoc_params(&func.params, "Parameters");
111 if !sig.private {
115 self.push_str("pub ");
116 }
117 if sig.unsafe_ {
118 self.push_str("unsafe ");
119 }
120 if sig.async_ {
121 self.push_str("async ");
122 }
123 self.push_str("fn ");
124 let func_name = if sig.use_item_name {
125 func.item_name()
126 } else {
127 &func.name
128 };
129 self.push_str(&to_rust_ident(func_name));
130 if let Some(generics) = &sig.generics {
131 self.push_str(generics);
132 }
133 self.push_str("(");
134 if let Some(arg) = &sig.self_arg {
135 self.push_str(arg);
136 self.push_str(",");
137 }
138 let mut params = Vec::new();
139 for (i, (name, param)) in func.params.iter().enumerate() {
140 if i == 0 && sig.self_is_first_param {
141 params.push("self".to_string());
142 continue;
143 }
144 let name = to_rust_ident(name);
145 self.push_str(&name);
146 params.push(name);
147 self.push_str(": ");
148 self.print_ty(iface, param, param_mode);
149 self.push_str(",");
150 }
151 self.push_str(")");
152 params
153 }
154
155 fn print_ty(&mut self, iface: &Interface, ty: &Type, mode: TypeMode) {
156 match ty {
157 Type::Id(t) => self.print_tyid(iface, *t, mode),
158 Type::Handle(r) => {
159 let mut info = TypeInfo::default();
160 info.has_handle = true;
161 let lt = self.lifetime_for(&info, mode);
162 if let Some(lt) = lt {
165 self.push_str("&");
166 if lt != "'_" {
167 self.push_str(lt);
168 }
169 self.push_str(" ");
170 }
171
172 let suffix = match self.handle_wrapper() {
173 Some(wrapper) => {
174 self.push_str(wrapper);
175 self.push_str("<");
176 ">"
177 }
178 None => "",
179 };
180 if self.handle_in_super() {
181 self.push_str("super::");
182 }
183 if let Some((proj, _)) = self.handle_projection() {
184 self.push_str(proj);
185 self.push_str("::");
186 }
187 self.push_str(&iface.resources[*r].name.to_camel_case());
188 self.push_str(suffix);
189 }
190
191 Type::Unit => self.push_str("()"),
192 Type::Bool => self.push_str("bool"),
193 Type::U8 => self.push_str("u8"),
194 Type::U16 => self.push_str("u16"),
195 Type::U32 => self.push_str("u32"),
196 Type::U64 => self.push_str("u64"),
197 Type::S8 => self.push_str("i8"),
198 Type::S16 => self.push_str("i16"),
199 Type::S32 => self.push_str("i32"),
200 Type::S64 => self.push_str("i64"),
201 Type::Float32 => self.push_str("f32"),
202 Type::Float64 => self.push_str("f64"),
203 Type::Char => self.push_str("char"),
204 Type::String => match mode {
205 TypeMode::AllBorrowed(lt) | TypeMode::LeafBorrowed(lt) => {
206 self.print_borrowed_str(lt)
207 }
208 TypeMode::Owned | TypeMode::HandlesBorrowed(_) => self.push_str("String"),
209 },
210 }
211 }
212
213 fn print_tyid(&mut self, iface: &Interface, id: TypeId, mode: TypeMode) {
214 let info = self.info(id);
215 let lt = self.lifetime_for(&info, mode);
216 let ty = &iface.types[id];
217 if ty.name.is_some() {
218 let name = if lt.is_some() {
219 self.param_name(iface, id)
220 } else {
221 self.result_name(iface, id)
222 };
223 self.push_str(&name);
224
225 if info.owns_data() && needs_generics(iface, &ty.kind) {
229 self.print_generics(&info, lt, false);
230 }
231
232 return;
233
234 fn needs_generics(iface: &Interface, ty: &TypeDefKind) -> bool {
235 match ty {
236 TypeDefKind::Variant(_)
237 | TypeDefKind::Record(_)
238 | TypeDefKind::Option(_)
239 | TypeDefKind::Expected(_)
240 | TypeDefKind::Future(_)
241 | TypeDefKind::Stream(_)
242 | TypeDefKind::List(_)
243 | TypeDefKind::Flags(_)
244 | TypeDefKind::Enum(_)
245 | TypeDefKind::Tuple(_)
246 | TypeDefKind::Union(_) => true,
247 TypeDefKind::Type(Type::Id(t)) => needs_generics(iface, &iface.types[*t].kind),
248 TypeDefKind::Type(Type::String) => true,
249 TypeDefKind::Type(Type::Handle(_)) => true,
250 TypeDefKind::Type(_) => false,
251 }
252 }
253 }
254
255 match &ty.kind {
256 TypeDefKind::List(t) => self.print_list(iface, t, mode),
257
258 TypeDefKind::Option(t) => {
259 self.push_str("Option<");
260 self.print_ty(iface, t, mode);
261 self.push_str(">");
262 }
263
264 TypeDefKind::Expected(e) => {
265 self.push_str("Result<");
266 self.print_ty(iface, &e.ok, mode);
267 self.push_str(",");
268 self.print_ty(iface, &e.err, mode);
269 self.push_str(">");
270 }
271
272 TypeDefKind::Variant(_) => panic!("unsupported anonymous variant"),
273
274 TypeDefKind::Tuple(t) => {
278 self.push_str("(");
279 for ty in t.types.iter() {
280 self.print_ty(iface, ty, mode);
281 self.push_str(",");
282 }
283 self.push_str(")");
284 }
285 TypeDefKind::Record(_) => {
286 panic!("unsupported anonymous type reference: record")
287 }
288 TypeDefKind::Flags(_) => {
289 panic!("unsupported anonymous type reference: flags")
290 }
291 TypeDefKind::Enum(_) => {
292 panic!("unsupported anonymous type reference: enum")
293 }
294 TypeDefKind::Union(_) => {
295 panic!("unsupported anonymous type reference: union")
296 }
297 TypeDefKind::Future(ty) => {
298 self.push_str("Future<");
299 self.print_ty(iface, ty, mode);
300 self.push_str(">");
301 }
302 TypeDefKind::Stream(stream) => {
303 self.push_str("Stream<");
304 self.print_ty(iface, &stream.element, mode);
305 self.push_str(",");
306 self.print_ty(iface, &stream.end, mode);
307 self.push_str(">");
308 }
309
310 TypeDefKind::Type(t) => self.print_ty(iface, t, mode),
311 }
312 }
313
314 fn print_list(&mut self, iface: &Interface, ty: &Type, mode: TypeMode) {
315 match mode {
316 TypeMode::AllBorrowed(lt) => {
317 self.print_borrowed_slice(iface, false, ty, lt);
318 }
319 TypeMode::LeafBorrowed(lt) => {
320 if iface.all_bits_valid(ty) {
321 self.print_borrowed_slice(iface, false, ty, lt);
322 } else {
323 self.push_str("Vec<");
324 self.print_ty(iface, ty, mode);
325 self.push_str(">");
326 }
327 }
328 TypeMode::HandlesBorrowed(_) | TypeMode::Owned => {
329 self.push_str("Vec<");
330 self.print_ty(iface, ty, mode);
331 self.push_str(">");
332 }
333 }
334 }
335
336 fn print_rust_slice(
337 &mut self,
338 iface: &Interface,
339 mutbl: bool,
340 ty: &Type,
341 lifetime: &'static str,
342 ) {
343 self.push_str("&");
344 if lifetime != "'_" {
345 self.push_str(lifetime);
346 self.push_str(" ");
347 }
348 if mutbl {
349 self.push_str(" mut ");
350 }
351 self.push_str("[");
352 self.print_ty(iface, ty, TypeMode::AllBorrowed(lifetime));
353 self.push_str("]");
354 }
355
356 fn print_generics(&mut self, info: &TypeInfo, lifetime: Option<&str>, bound: bool) {
357 let proj = if info.has_handle {
358 self.handle_projection()
359 } else {
360 None
361 };
362 if lifetime.is_none() && proj.is_none() {
363 return;
364 }
365 self.push_str("<");
366 if let Some(lt) = lifetime {
367 self.push_str(lt);
368 self.push_str(",");
369 }
370 if let Some((proj, trait_bound)) = proj {
371 self.push_str(proj);
372 if bound {
373 self.push_str(": ");
374 self.push_str(&trait_bound);
375 }
376 }
377 self.push_str(">");
378 }
379
380 fn int_repr(&mut self, repr: Int) {
381 self.push_str(int_repr(repr));
382 }
383
384 fn wasm_type(&mut self, ty: WasmType) {
385 self.push_str(wasm_type(ty));
386 }
387
388 fn modes_of(&self, iface: &Interface, ty: TypeId) -> Vec<(String, TypeMode)> {
389 let info = self.info(ty);
390 let mut result = Vec::new();
391 if info.param || self.always_generate_structs() {
392 result.push((self.param_name(iface, ty), self.default_param_mode()));
393 }
394 if info.result
395 && (!info.param || self.always_generate_structs() || self.uses_two_names(&info))
396 {
397 result.push((self.result_name(iface, ty), TypeMode::Owned));
398 }
399 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::Expected(_) => 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_expected(
710 &mut self,
711 iface: &Interface,
712 id: TypeId,
713 expected: &Expected,
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, &expected.ok, mode);
725 self.push_str(",");
726 self.print_ty(iface, &expected.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('{');
977 for (field, val) in ty.fields.iter().zip(operands) {
978 result.push_str(&to_rust_ident(&field.name));
979 result.push(':');
980 result.push_str(val);
981 result.push_str(", ");
982 }
983 result.push('}');
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}