wit_bindgen_gen_rust_lib/
lib.rs

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    /// Return true iff the generator can use `std` features in its output.
20    fn use_std(&self) -> bool {
21        true
22    }
23
24    /// Return the fully-qualified name for the `Vec` type to use.
25    fn vec_name(&self) -> &'static str;
26
27    /// Return the fully-qualified name for the `String` type to use.
28    fn string_name(&self) -> &'static str;
29
30    /// Return true iff the generator should use `&[u8]` instead of `&str` in bindings.
31    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        // let docs = docs
57        //     .iter()
58        //     .filter(|param| param.docs.trim().len() > 0)
59        //     .collect::<Vec<_>>();
60        // if docs.len() == 0 {
61        //     return;
62        // }
63
64        // self.push_str("///\n");
65        // self.push_str("/// ## ");
66        // self.push_str(header);
67        // self.push_str("\n");
68        // self.push_str("///\n");
69
70        // for param in docs {
71        //     for (i, line) in param.docs.lines().enumerate() {
72        //         self.push_str("/// ");
73        //         // Currently wasi only has at most one return value, so there's no
74        //         // need to indent it or name it.
75        //         if header != "Return" {
76        //             if i == 0 {
77        //                 self.push_str("* `");
78        //                 self.push_str(to_rust_ident(param.name.as_str()));
79        //                 self.push_str("` - ");
80        //             } else {
81        //                 self.push_str("  ");
82        //             }
83        //         }
84        //         self.push_str(line);
85        //         self.push_str("\n");
86        //     }
87        // }
88    }
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        // TODO: re-add this when docs are back
111        // self.rustdoc_params(&func.results, "Return");
112
113        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 the type recursively owns data and it's a
226            // variant/record/list, then we need to place the
227            // lifetime parameter on the type as well.
228            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            // Tuple-like records are mapped directly to Rust tuples of
277            // types. Note the trailing comma after each member to
278            // appropriately handle 1-tuples.
279            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    /// Writes the camel-cased 'name' of the passed type to `out`, as used to name union variants.
389    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    /// Returns the names for the cases of the passed union.
450    fn union_case_names(&self, union: &Union) -> Vec<String> {
451        enum UsedState<'a> {
452            /// This name has been used once before.
453            ///
454            /// Contains a reference to the name given to the first usage so that a suffix can be added to it.
455            Once(&'a mut String),
456            /// This name has already been used multiple times.
457            ///
458            /// Contains the number of times this has already been used.
459            Multiple(usize),
460        }
461
462        // A `Vec` of the names we're assigning each of the union's cases in order.
463        let mut case_names = vec![String::new(); union.cases.len()];
464        // A map from case names to their `UsedState`.
465        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                    // Initialise this name's `UsedState`, with a mutable reference to this name
472                    // in case we have to add a suffix to it later.
473                    used.insert(name.clone(), UsedState::Once(name));
474                    // Since this is the first (and potentially only) usage of this name,
475                    // we don't need to add a suffix here.
476                }
477                Some(state) => match state {
478                    UsedState::Multiple(n) => {
479                        // Add a suffix of the index of this usage.
480                        write!(name, "{n}").unwrap();
481                        // Add one to the number of times this type has been used.
482                        *n += 1;
483                    }
484                    UsedState::Once(first) => {
485                        // Add a suffix of 0 to the first usage.
486                        first.push('0');
487                        // We now get a suffix of 1.
488                        name.push('1');
489                        // Then update the state.
490                        *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        // Auto-synthesize an implementation of the standard `Error` trait for
837        // error-looking types based on their name.
838        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        // Escape Rust keywords.
1114        // Source: https://doc.rust-lang.org/reference/keywords.html
1115        "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}