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