wit_bindgen_rust_lib/
lib.rs

1use heck::*;
2use std::fmt;
3use std::str::FromStr;
4use wit_bindgen_core::abi::{Bitcast, LiftLower, WasmType};
5use wit_bindgen_core::{wit_parser::*, TypeInfo, Types};
6
7#[derive(Debug, Copy, Clone, PartialEq)]
8pub enum TypeMode {
9    Owned,
10    AllBorrowed(&'static str),
11    LeafBorrowed(&'static str),
12    HandlesBorrowed(&'static str),
13}
14
15#[derive(Default, Debug, Clone, Copy)]
16pub enum Ownership {
17    /// Generated types will be composed entirely of owning fields, regardless
18    /// of whether they are used as parameters to imports or not.
19    #[default]
20    Owning,
21
22    /// Generated types used as parameters to imports will be "deeply
23    /// borrowing", i.e. contain references rather than owned values when
24    /// applicable.
25    Borrowing {
26        /// Whether or not to generate "duplicate" type definitions for a single
27        /// WIT type if necessary, for example if it's used as both an import
28        /// and an export, or if it's used both as a parameter to an import and
29        /// a return value from an import.
30        duplicate_if_necessary: bool,
31    },
32}
33
34impl FromStr for Ownership {
35    type Err = String;
36
37    fn from_str(s: &str) -> Result<Self, Self::Err> {
38        match s {
39            "owning" => Ok(Self::Owning),
40            "borrowing" => Ok(Self::Borrowing {
41                duplicate_if_necessary: false,
42            }),
43            "borrowing-duplicate-if-necessary" => Ok(Self::Borrowing {
44                duplicate_if_necessary: true,
45            }),
46            _ => Err(format!(
47                "unrecognized ownership: `{s}`; \
48                 expected `owning`, `borrowing`, or `borrowing-duplicate-if-necessary`"
49            )),
50        }
51    }
52}
53
54impl fmt::Display for Ownership {
55    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56        f.write_str(match self {
57            Ownership::Owning => "owning",
58            Ownership::Borrowing {
59                duplicate_if_necessary: false,
60            } => "borrowing",
61            Ownership::Borrowing {
62                duplicate_if_necessary: true,
63            } => "borrowing-duplicate-if-necessary",
64        })
65    }
66}
67
68pub trait RustGenerator<'a> {
69    fn resolve(&self) -> &'a Resolve;
70    fn path_to_interface(&self, interface: InterfaceId) -> Option<String>;
71
72    /// Whether to generate owning or borrowing type definitions.
73    fn ownership(&self) -> Ownership;
74
75    /// Return true iff the generator should qualify uses of `std` features with
76    /// `#[cfg(feature = "std")]` in its output.
77    fn std_feature(&self) -> bool {
78        true
79    }
80
81    /// Pushes the name of the `Vec` type to use.
82    fn push_vec_name(&mut self);
83
84    /// Pushes the name of the `String` type to use.
85    fn push_string_name(&mut self);
86
87    /// Return true iff the generator should use `&[u8]` instead of `&str` in bindings.
88    fn use_raw_strings(&self) -> bool {
89        false
90    }
91
92    fn is_exported_resource(&self, ty: TypeId) -> bool;
93
94    fn mark_resource_owned(&mut self, resource: TypeId);
95
96    fn push_str(&mut self, s: &str);
97    fn info(&self, ty: TypeId) -> TypeInfo;
98    fn types_mut(&mut self) -> &mut Types;
99    fn print_borrowed_slice(
100        &mut self,
101        mutbl: bool,
102        ty: &Type,
103        lifetime: &'static str,
104        mode: TypeMode,
105    );
106    fn print_borrowed_str(&mut self, lifetime: &'static str);
107
108    fn rustdoc(&mut self, docs: &Docs) {
109        let docs = match &docs.contents {
110            Some(docs) => docs,
111            None => return,
112        };
113        for line in docs.trim().lines() {
114            self.push_str("/// ");
115            self.push_str(line);
116            self.push_str("\n");
117        }
118    }
119
120    fn rustdoc_params(&mut self, docs: &[(String, Type)], header: &str) {
121        let _ = (docs, header);
122        // let docs = docs
123        //     .iter()
124        //     .filter(|param| param.docs.trim().len() > 0)
125        //     .collect::<Vec<_>>();
126        // if docs.len() == 0 {
127        //     return;
128        // }
129
130        // self.push_str("///\n");
131        // self.push_str("/// ## ");
132        // self.push_str(header);
133        // self.push_str("\n");
134        // self.push_str("///\n");
135
136        // for param in docs {
137        //     for (i, line) in param.docs.lines().enumerate() {
138        //         self.push_str("/// ");
139        //         // Currently wasi only has at most one return value, so there's no
140        //         // need to indent it or name it.
141        //         if header != "Return" {
142        //             if i == 0 {
143        //                 self.push_str("* `");
144        //                 self.push_str(to_rust_ident(param.name.as_str()));
145        //                 self.push_str("` - ");
146        //             } else {
147        //                 self.push_str("  ");
148        //             }
149        //         }
150        //         self.push_str(line);
151        //         self.push_str("\n");
152        //     }
153        // }
154    }
155
156    fn print_signature(
157        &mut self,
158        func: &Function,
159        param_mode: TypeMode,
160        sig: &FnSig,
161    ) -> Vec<String> {
162        let params = self.print_docs_and_params(func, param_mode, &sig);
163        if let FunctionKind::Constructor(_) = &func.kind {
164            self.push_str(" -> Self")
165        } else {
166            self.print_results(&func.results, TypeMode::Owned);
167        }
168        params
169    }
170
171    fn print_docs_and_params(
172        &mut self,
173        func: &Function,
174        param_mode: TypeMode,
175        sig: &FnSig,
176    ) -> Vec<String> {
177        self.rustdoc(&func.docs);
178        self.rustdoc_params(&func.params, "Parameters");
179        // TODO: re-add this when docs are back
180        // self.rustdoc_params(&func.results, "Return");
181
182        if !sig.private {
183            self.push_str("pub ");
184        }
185        if sig.unsafe_ {
186            self.push_str("unsafe ");
187        }
188        if sig.async_ {
189            self.push_str("async ");
190        }
191        self.push_str("fn ");
192        let func_name = if sig.use_item_name {
193            if let FunctionKind::Constructor(_) = &func.kind {
194                "new"
195            } else {
196                func.item_name()
197            }
198        } else {
199            &func.name
200        };
201        self.push_str(&to_rust_ident(&func_name));
202        if let Some(generics) = &sig.generics {
203            self.push_str(generics);
204        }
205        self.push_str("(");
206        if let Some(arg) = &sig.self_arg {
207            self.push_str(arg);
208            self.push_str(",");
209        }
210        let mut params = Vec::new();
211        for (i, (name, param)) in func.params.iter().enumerate() {
212            if i == 0 && sig.self_is_first_param {
213                params.push("self".to_string());
214                continue;
215            }
216            let name = to_rust_ident(name);
217            self.push_str(&name);
218            params.push(name);
219            self.push_str(": ");
220            self.print_ty(param, param_mode);
221            self.push_str(",");
222        }
223        self.push_str(")");
224        params
225    }
226
227    fn print_results(&mut self, results: &Results, mode: TypeMode) {
228        match results.len() {
229            0 => {}
230            1 => {
231                self.push_str(" -> ");
232                self.print_ty(results.iter_types().next().unwrap(), mode);
233            }
234            _ => {
235                self.push_str(" -> (");
236                for ty in results.iter_types() {
237                    self.print_ty(ty, mode);
238                    self.push_str(", ")
239                }
240                self.push_str(")")
241            }
242        }
243    }
244
245    fn print_ty(&mut self, ty: &Type, mode: TypeMode) {
246        match ty {
247            Type::Id(t) => self.print_tyid(*t, mode),
248            Type::Bool => self.push_str("bool"),
249            Type::U8 => self.push_str("u8"),
250            Type::U16 => self.push_str("u16"),
251            Type::U32 => self.push_str("u32"),
252            Type::U64 => self.push_str("u64"),
253            Type::S8 => self.push_str("i8"),
254            Type::S16 => self.push_str("i16"),
255            Type::S32 => self.push_str("i32"),
256            Type::S64 => self.push_str("i64"),
257            Type::Float32 => self.push_str("f32"),
258            Type::Float64 => self.push_str("f64"),
259            Type::Char => self.push_str("char"),
260            Type::String => match mode {
261                TypeMode::AllBorrowed(lt) | TypeMode::LeafBorrowed(lt) => {
262                    self.print_borrowed_str(lt)
263                }
264                TypeMode::Owned | TypeMode::HandlesBorrowed(_) => {
265                    if self.use_raw_strings() {
266                        self.push_vec_name();
267                        self.push_str("::<u8>");
268                    } else {
269                        self.push_string_name();
270                    }
271                }
272            },
273        }
274    }
275
276    fn print_optional_ty(&mut self, ty: Option<&Type>, mode: TypeMode) {
277        match ty {
278            Some(ty) => self.print_ty(ty, mode),
279            None => self.push_str("()"),
280        }
281    }
282
283    fn type_path(&self, id: TypeId, owned: bool) -> String {
284        self.type_path_with_name(
285            id,
286            if owned {
287                self.result_name(id)
288            } else {
289                self.param_name(id)
290            },
291        )
292    }
293
294    fn type_path_with_name(&self, id: TypeId, name: String) -> String {
295        if let TypeOwner::Interface(id) = self.resolve().types[id].owner {
296            if let Some(path) = self.path_to_interface(id) {
297                return format!("{path}::{name}");
298            }
299        }
300        name
301    }
302
303    fn print_tyid(&mut self, id: TypeId, mode: TypeMode) {
304        let info = self.info(id);
305        let lt = self.lifetime_for(&info, mode);
306        let ty = &self.resolve().types[id];
307        if ty.name.is_some() {
308            // If `mode` is borrowed then that means literal ownership of the
309            // input type is not necessarily required. In this situation we
310            // ideally want to put a `&` in front to statically indicate this.
311            // That's not required in all situations however and is only really
312            // critical for lists which otherwise would transfer ownership of
313            // the allocation to this function.
314            //
315            // Note, though, that if the type has an `own<T>` inside of it then
316            // it is actually required that we take ownership since Rust is
317            // losing access to those handles.
318            //
319            // Check here if the type has the right shape and if we're in the
320            // right mode, and if those conditions are met a lifetime is
321            // printed.
322            if info.has_list && !info.has_own_handle {
323                if let TypeMode::AllBorrowed(lt)
324                | TypeMode::LeafBorrowed(lt)
325                | TypeMode::HandlesBorrowed(lt) = mode
326                {
327                    self.push_str("&");
328                    if lt != "'_" {
329                        self.push_str(lt);
330                        self.push_str(" ");
331                    }
332                }
333            }
334            let name = self.type_path(id, lt.is_none());
335            self.push_str(&name);
336
337            // If the type recursively owns data and it's a
338            // variant/record/list, then we need to place the
339            // lifetime parameter on the type as well.
340            if (info.has_list || info.has_borrow_handle)
341                && !info.has_own_handle
342                && needs_generics(self.resolve(), &ty.kind)
343            {
344                self.print_generics(lt);
345            }
346
347            return;
348
349            fn needs_generics(resolve: &Resolve, ty: &TypeDefKind) -> bool {
350                match ty {
351                    TypeDefKind::Variant(_)
352                    | TypeDefKind::Record(_)
353                    | TypeDefKind::Option(_)
354                    | TypeDefKind::Result(_)
355                    | TypeDefKind::Future(_)
356                    | TypeDefKind::Stream(_)
357                    | TypeDefKind::List(_)
358                    | TypeDefKind::Flags(_)
359                    | TypeDefKind::Enum(_)
360                    | TypeDefKind::Tuple(_) => true,
361                    TypeDefKind::Type(Type::Id(t)) => {
362                        needs_generics(resolve, &resolve.types[*t].kind)
363                    }
364                    TypeDefKind::Type(Type::String) => true,
365                    TypeDefKind::Handle(Handle::Borrow(_)) => true,
366                    TypeDefKind::Resource | TypeDefKind::Handle(_) | TypeDefKind::Type(_) => false,
367                    TypeDefKind::Unknown => unreachable!(),
368                }
369            }
370        }
371
372        match &ty.kind {
373            TypeDefKind::List(t) => self.print_list(t, mode),
374
375            TypeDefKind::Option(t) => {
376                self.push_str("Option<");
377                self.print_ty(t, mode);
378                self.push_str(">");
379            }
380
381            TypeDefKind::Result(r) => {
382                self.push_str("Result<");
383                self.print_optional_ty(r.ok.as_ref(), mode);
384                self.push_str(",");
385                self.print_optional_ty(r.err.as_ref(), mode);
386                self.push_str(">");
387            }
388
389            TypeDefKind::Variant(_) => panic!("unsupported anonymous variant"),
390
391            // Tuple-like records are mapped directly to Rust tuples of
392            // types. Note the trailing comma after each member to
393            // appropriately handle 1-tuples.
394            TypeDefKind::Tuple(t) => {
395                self.push_str("(");
396                for ty in t.types.iter() {
397                    self.print_ty(ty, mode);
398                    self.push_str(",");
399                }
400                self.push_str(")");
401            }
402            TypeDefKind::Resource => {
403                panic!("unsupported anonymous type reference: resource")
404            }
405            TypeDefKind::Record(_) => {
406                panic!("unsupported anonymous type reference: record")
407            }
408            TypeDefKind::Flags(_) => {
409                panic!("unsupported anonymous type reference: flags")
410            }
411            TypeDefKind::Enum(_) => {
412                panic!("unsupported anonymous type reference: enum")
413            }
414            TypeDefKind::Future(ty) => {
415                self.push_str("Future<");
416                self.print_optional_ty(ty.as_ref(), mode);
417                self.push_str(">");
418            }
419            TypeDefKind::Stream(stream) => {
420                self.push_str("Stream<");
421                self.print_optional_ty(stream.element.as_ref(), mode);
422                self.push_str(",");
423                self.print_optional_ty(stream.end.as_ref(), mode);
424                self.push_str(">");
425            }
426
427            TypeDefKind::Handle(Handle::Own(ty)) => {
428                self.mark_resource_owned(*ty);
429                self.print_ty(&Type::Id(*ty), mode);
430            }
431
432            TypeDefKind::Handle(Handle::Borrow(ty)) => {
433                self.push_str("&");
434                if let TypeMode::AllBorrowed(lt)
435                | TypeMode::LeafBorrowed(lt)
436                | TypeMode::HandlesBorrowed(lt) = mode
437                {
438                    if lt != "'_" {
439                        self.push_str(lt);
440                        self.push_str(" ");
441                    }
442                }
443                if self.is_exported_resource(*ty) {
444                    self.push_str(
445                        &self.type_path_with_name(
446                            *ty,
447                            self.resolve().types[*ty]
448                                .name
449                                .as_deref()
450                                .unwrap()
451                                .to_upper_camel_case(),
452                        ),
453                    );
454                } else {
455                    self.print_ty(&Type::Id(*ty), mode);
456                }
457            }
458
459            TypeDefKind::Type(t) => self.print_ty(t, mode),
460
461            TypeDefKind::Unknown => unreachable!(),
462        }
463    }
464
465    fn print_list(&mut self, ty: &Type, mode: TypeMode) {
466        let next_mode = if matches!(self.ownership(), Ownership::Owning) {
467            if let TypeMode::HandlesBorrowed(_) = mode {
468                mode
469            } else {
470                TypeMode::Owned
471            }
472        } else {
473            mode
474        };
475        // Lists with `own` handles must always be owned
476        let mode = match *ty {
477            Type::Id(id) if self.info(id).has_own_handle => TypeMode::Owned,
478            _ => mode,
479        };
480        match mode {
481            TypeMode::AllBorrowed(lt) => {
482                self.print_borrowed_slice(false, ty, lt, next_mode);
483            }
484            TypeMode::LeafBorrowed(lt) => {
485                if self.resolve().all_bits_valid(ty) {
486                    self.print_borrowed_slice(false, ty, lt, next_mode);
487                } else {
488                    self.push_vec_name();
489                    self.push_str("::<");
490                    self.print_ty(ty, next_mode);
491                    self.push_str(">");
492                }
493            }
494            TypeMode::Owned | TypeMode::HandlesBorrowed(_) => {
495                self.push_vec_name();
496                self.push_str("::<");
497                self.print_ty(ty, next_mode);
498                self.push_str(">");
499            }
500        }
501    }
502
503    fn print_rust_slice(&mut self, mutbl: bool, ty: &Type, lifetime: &'static str, mode: TypeMode) {
504        self.push_str("&");
505        if lifetime != "'_" {
506            self.push_str(lifetime);
507            self.push_str(" ");
508        }
509        if mutbl {
510            self.push_str(" mut ");
511        }
512        self.push_str("[");
513        self.print_ty(ty, mode);
514        self.push_str("]");
515    }
516
517    fn print_generics(&mut self, lifetime: Option<&str>) {
518        if lifetime.is_none() {
519            return;
520        }
521        self.push_str("<");
522        if let Some(lt) = lifetime {
523            self.push_str(lt);
524            self.push_str(",");
525        }
526        self.push_str(">");
527    }
528
529    fn int_repr(&mut self, repr: Int) {
530        self.push_str(int_repr(repr));
531    }
532
533    fn wasm_type(&mut self, ty: WasmType) {
534        self.push_str(wasm_type(ty));
535    }
536
537    fn modes_of(&self, ty: TypeId) -> Vec<(String, TypeMode)> {
538        let info = self.info(ty);
539        // If this type isn't actually used, no need to generate it.
540        if !info.owned && !info.borrowed {
541            return Vec::new();
542        }
543        let mut result = Vec::new();
544
545        // Prioritize generating an "owned" type. This is done to simplify
546        // generated bindings by default. Borrowed handles always use a borrow,
547        // however.
548        let first_mode = if info.owned
549            || !info.borrowed
550            || matches!(self.ownership(), Ownership::Owning)
551            || info.has_own_handle
552        {
553            if info.has_borrow_handle {
554                TypeMode::HandlesBorrowed("'a")
555            } else {
556                TypeMode::Owned
557            }
558        } else {
559            assert!(!self.uses_two_names(&info));
560            TypeMode::AllBorrowed("'a")
561        };
562        result.push((self.result_name(ty), first_mode));
563        if self.uses_two_names(&info) {
564            result.push((self.param_name(ty), TypeMode::AllBorrowed("'a")));
565        }
566        return result;
567    }
568
569    fn print_typedef_record(
570        &mut self,
571        id: TypeId,
572        record: &Record,
573        docs: &Docs,
574        derive_component: bool,
575    ) {
576        let info = self.info(id);
577        for (name, mode) in self.modes_of(id) {
578            let lt = self.lifetime_for(&info, mode);
579            self.rustdoc(docs);
580
581            if derive_component {
582                self.push_str("#[derive(wasmtime::component::ComponentType)]\n");
583                if lt.is_none() {
584                    self.push_str("#[derive(wasmtime::component::Lift)]\n");
585                }
586                self.push_str("#[derive(wasmtime::component::Lower)]\n");
587                self.push_str("#[component(record)]\n");
588            }
589
590            if info.is_copy() {
591                self.push_str("#[repr(C)]\n");
592                self.push_str("#[derive(Copy, Clone)]\n");
593            } else if info.is_clone() {
594                self.push_str("#[derive(Clone)]\n");
595            }
596            self.push_str(&format!("pub struct {}", name));
597            self.print_generics(lt);
598            self.push_str(" {\n");
599            for field in record.fields.iter() {
600                self.rustdoc(&field.docs);
601                if derive_component {
602                    self.push_str(&format!("#[component(name = \"{}\")]\n", field.name));
603                }
604                self.push_str("pub ");
605                self.push_str(&to_rust_ident(&field.name));
606                self.push_str(": ");
607                self.print_ty(&field.ty, mode);
608                self.push_str(",\n");
609            }
610            self.push_str("}\n");
611
612            self.push_str("impl");
613            self.print_generics(lt);
614            self.push_str(" ::core::fmt::Debug for ");
615            self.push_str(&name);
616            self.print_generics(lt);
617            self.push_str(" {\n");
618            self.push_str(
619                "fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n",
620            );
621            self.push_str(&format!("f.debug_struct(\"{}\")", name));
622            for field in record.fields.iter() {
623                self.push_str(&format!(
624                    ".field(\"{}\", &self.{})",
625                    field.name,
626                    to_rust_ident(&field.name)
627                ));
628            }
629            self.push_str(".finish()\n");
630            self.push_str("}\n");
631            self.push_str("}\n");
632
633            if info.error {
634                self.push_str("impl");
635                self.print_generics(lt);
636                self.push_str(" ::core::fmt::Display for ");
637                self.push_str(&name);
638                self.print_generics(lt);
639                self.push_str(" {\n");
640                self.push_str(
641                    "fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n",
642                );
643                self.push_str("write!(f, \"{:?}\", self)\n");
644                self.push_str("}\n");
645                self.push_str("}\n");
646                if self.std_feature() {
647                    self.push_str("#[cfg(feature = \"std\")]");
648                }
649                self.push_str("impl std::error::Error for ");
650                self.push_str(&name);
651                self.push_str("{}\n");
652            }
653        }
654    }
655
656    fn print_typedef_tuple(&mut self, id: TypeId, tuple: &Tuple, docs: &Docs) {
657        let info = self.info(id);
658        for (name, mode) in self.modes_of(id) {
659            let lt = self.lifetime_for(&info, mode);
660            self.rustdoc(docs);
661            self.push_str(&format!("pub type {}", name));
662            self.print_generics(lt);
663            self.push_str(" = (");
664            for ty in tuple.types.iter() {
665                self.print_ty(ty, mode);
666                self.push_str(",");
667            }
668            self.push_str(");\n");
669        }
670    }
671
672    fn print_typedef_variant(
673        &mut self,
674        id: TypeId,
675        variant: &Variant,
676        docs: &Docs,
677        derive_component: bool,
678    ) where
679        Self: Sized,
680    {
681        self.print_rust_enum(
682            id,
683            variant.cases.iter().map(|c| {
684                (
685                    c.name.to_upper_camel_case(),
686                    Some(c.name.clone()),
687                    &c.docs,
688                    c.ty.as_ref(),
689                )
690            }),
691            docs,
692            if derive_component {
693                Some("variant")
694            } else {
695                None
696            },
697        );
698    }
699
700    fn print_rust_enum<'b>(
701        &mut self,
702        id: TypeId,
703        cases: impl IntoIterator<Item = (String, Option<String>, &'b Docs, Option<&'b Type>)> + Clone,
704        docs: &Docs,
705        derive_component: Option<&str>,
706    ) where
707        Self: Sized,
708    {
709        let info = self.info(id);
710
711        for (name, mode) in self.modes_of(id) {
712            self.rustdoc(docs);
713            let lt = self.lifetime_for(&info, mode);
714            if let Some(derive_component) = derive_component {
715                self.push_str("#[derive(wasmtime::component::ComponentType)]\n");
716                if lt.is_none() {
717                    self.push_str("#[derive(wasmtime::component::Lift)]\n");
718                }
719                self.push_str("#[derive(wasmtime::component::Lower)]\n");
720                self.push_str(&format!("#[component({})]\n", derive_component));
721            }
722            if info.is_copy() {
723                self.push_str("#[derive(Copy, Clone)]\n");
724            } else if info.is_clone() {
725                self.push_str("#[derive(Clone)]\n");
726            }
727            self.push_str(&format!("pub enum {name}"));
728            self.print_generics(lt);
729            self.push_str("{\n");
730            for (case_name, component_name, docs, payload) in cases.clone() {
731                self.rustdoc(docs);
732                if derive_component.is_some() {
733                    if let Some(n) = component_name {
734                        self.push_str(&format!("#[component(name = \"{}\")] ", n));
735                    }
736                }
737                self.push_str(&case_name);
738                if let Some(ty) = payload {
739                    self.push_str("(");
740                    self.print_ty(ty, mode);
741                    self.push_str(")")
742                }
743                self.push_str(",\n");
744            }
745            self.push_str("}\n");
746
747            self.print_rust_enum_debug(
748                id,
749                mode,
750                &name,
751                cases
752                    .clone()
753                    .into_iter()
754                    .map(|(name, _attr, _docs, ty)| (name, ty)),
755            );
756
757            if info.error {
758                self.push_str("impl");
759                self.print_generics(lt);
760                self.push_str(" ::core::fmt::Display for ");
761                self.push_str(&name);
762                self.print_generics(lt);
763                self.push_str(" {\n");
764                self.push_str(
765                    "fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n",
766                );
767                self.push_str("write!(f, \"{:?}\", self)\n");
768                self.push_str("}\n");
769                self.push_str("}\n");
770                self.push_str("\n");
771
772                if self.std_feature() {
773                    self.push_str("#[cfg(feature = \"std\")]");
774                }
775                self.push_str("impl");
776                self.print_generics(lt);
777                self.push_str(" std::error::Error for ");
778                self.push_str(&name);
779                self.print_generics(lt);
780                self.push_str(" {}\n");
781            }
782        }
783    }
784
785    fn print_rust_enum_debug<'b>(
786        &mut self,
787        id: TypeId,
788        mode: TypeMode,
789        name: &str,
790        cases: impl IntoIterator<Item = (String, Option<&'b Type>)>,
791    ) where
792        Self: Sized,
793    {
794        let info = self.info(id);
795        let lt = self.lifetime_for(&info, mode);
796        self.push_str("impl");
797        self.print_generics(lt);
798        self.push_str(" ::core::fmt::Debug for ");
799        self.push_str(name);
800        self.print_generics(lt);
801        self.push_str(" {\n");
802        self.push_str(
803            "fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n",
804        );
805        self.push_str("match self {\n");
806        for (case_name, payload) in cases {
807            self.push_str(name);
808            self.push_str("::");
809            self.push_str(&case_name);
810            if payload.is_some() {
811                self.push_str("(e)");
812            }
813            self.push_str(" => {\n");
814            self.push_str(&format!("f.debug_tuple(\"{}::{}\")", name, case_name));
815            if payload.is_some() {
816                self.push_str(".field(e)");
817            }
818            self.push_str(".finish()\n");
819            self.push_str("}\n");
820        }
821        self.push_str("}\n");
822        self.push_str("}\n");
823        self.push_str("}\n");
824    }
825
826    fn print_typedef_option(&mut self, id: TypeId, payload: &Type, docs: &Docs) {
827        let info = self.info(id);
828
829        for (name, mode) in self.modes_of(id) {
830            self.rustdoc(docs);
831            let lt = self.lifetime_for(&info, mode);
832            self.push_str(&format!("pub type {}", name));
833            self.print_generics(lt);
834            self.push_str("= Option<");
835            self.print_ty(payload, mode);
836            self.push_str(">;\n");
837        }
838    }
839
840    fn print_typedef_result(&mut self, id: TypeId, result: &Result_, docs: &Docs) {
841        let info = self.info(id);
842
843        for (name, mode) in self.modes_of(id) {
844            self.rustdoc(docs);
845            let lt = self.lifetime_for(&info, mode);
846            self.push_str(&format!("pub type {}", name));
847            self.print_generics(lt);
848            self.push_str("= Result<");
849            self.print_optional_ty(result.ok.as_ref(), mode);
850            self.push_str(",");
851            self.print_optional_ty(result.err.as_ref(), mode);
852            self.push_str(">;\n");
853        }
854    }
855
856    fn print_typedef_enum(
857        &mut self,
858        id: TypeId,
859        name: &str,
860        enum_: &Enum,
861        docs: &Docs,
862        attrs: &[String],
863        case_attr: Box<dyn Fn(&EnumCase) -> String>,
864    ) where
865        Self: Sized,
866    {
867        let info = self.info(id);
868
869        let name = to_upper_camel_case(name);
870        self.rustdoc(docs);
871        for attr in attrs {
872            self.push_str(&format!("{}\n", attr));
873        }
874        self.push_str("#[repr(");
875        self.int_repr(enum_.tag());
876        self.push_str(")]\n#[derive(Clone, Copy, PartialEq, Eq)]\n");
877        self.push_str(&format!("pub enum {name} {{\n"));
878        for case in enum_.cases.iter() {
879            self.rustdoc(&case.docs);
880            self.push_str(&case_attr(case));
881            self.push_str(&case.name.to_upper_camel_case());
882            self.push_str(",\n");
883        }
884        self.push_str("}\n");
885
886        // Auto-synthesize an implementation of the standard `Error` trait for
887        // error-looking types based on their name.
888        if info.error {
889            self.push_str("impl ");
890            self.push_str(&name);
891            self.push_str("{\n");
892
893            self.push_str("pub fn name(&self) -> &'static str {\n");
894            self.push_str("match self {\n");
895            for case in enum_.cases.iter() {
896                self.push_str(&name);
897                self.push_str("::");
898                self.push_str(&case.name.to_upper_camel_case());
899                self.push_str(" => \"");
900                self.push_str(case.name.as_str());
901                self.push_str("\",\n");
902            }
903            self.push_str("}\n");
904            self.push_str("}\n");
905
906            self.push_str("pub fn message(&self) -> &'static str {\n");
907            self.push_str("match self {\n");
908            for case in enum_.cases.iter() {
909                self.push_str(&name);
910                self.push_str("::");
911                self.push_str(&case.name.to_upper_camel_case());
912                self.push_str(" => \"");
913                if let Some(contents) = &case.docs.contents {
914                    self.push_str(contents.trim());
915                }
916                self.push_str("\",\n");
917            }
918            self.push_str("}\n");
919            self.push_str("}\n");
920
921            self.push_str("}\n");
922
923            self.push_str("impl ::core::fmt::Debug for ");
924            self.push_str(&name);
925            self.push_str(
926                "{\nfn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n",
927            );
928            self.push_str("f.debug_struct(\"");
929            self.push_str(&name);
930            self.push_str("\")\n");
931            self.push_str(".field(\"code\", &(*self as i32))\n");
932            self.push_str(".field(\"name\", &self.name())\n");
933            self.push_str(".field(\"message\", &self.message())\n");
934            self.push_str(".finish()\n");
935            self.push_str("}\n");
936            self.push_str("}\n");
937
938            self.push_str("impl ::core::fmt::Display for ");
939            self.push_str(&name);
940            self.push_str(
941                "{\nfn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {\n",
942            );
943            self.push_str("write!(f, \"{} (error {})\", self.name(), *self as i32)\n");
944            self.push_str("}\n");
945            self.push_str("}\n");
946            self.push_str("\n");
947            if self.std_feature() {
948                self.push_str("#[cfg(feature = \"std\")]");
949            }
950            self.push_str("impl std::error::Error for ");
951            self.push_str(&name);
952            self.push_str("{}\n");
953        } else {
954            self.print_rust_enum_debug(
955                id,
956                TypeMode::Owned,
957                &name,
958                enum_
959                    .cases
960                    .iter()
961                    .map(|c| (c.name.to_upper_camel_case(), None)),
962            )
963        }
964    }
965
966    fn print_typedef_alias(&mut self, id: TypeId, ty: &Type, docs: &Docs) {
967        if self.is_exported_resource(id) {
968            let target = dealias(self.resolve(), id);
969            let ty = &self.resolve().types[target];
970            // TODO: We could wait until we know how a resource (and its
971            // aliases) is used prior to generating declarations.  For example,
972            // if only borrows are used, no need to generate the `Own{name}`
973            // version.
974            self.mark_resource_owned(target);
975            for prefix in ["Own", ""] {
976                self.rustdoc(docs);
977                self.push_str(&format!(
978                    "pub type {prefix}{} = {};\n",
979                    self.resolve().types[id]
980                        .name
981                        .as_deref()
982                        .unwrap()
983                        .to_upper_camel_case(),
984                    self.type_path_with_name(
985                        target,
986                        format!(
987                            "{prefix}{}",
988                            ty.name.as_deref().unwrap().to_upper_camel_case()
989                        )
990                    )
991                ));
992            }
993        } else {
994            let info = self.info(id);
995            for (name, mode) in self.modes_of(id) {
996                self.rustdoc(docs);
997                self.push_str(&format!("pub type {name}"));
998                let lt = self.lifetime_for(&info, mode);
999                self.print_generics(lt);
1000                self.push_str(" = ");
1001                self.print_ty(ty, mode);
1002                self.push_str(";\n");
1003            }
1004        }
1005    }
1006
1007    fn print_type_list(&mut self, id: TypeId, ty: &Type, docs: &Docs) {
1008        let info = self.info(id);
1009        for (name, mode) in self.modes_of(id) {
1010            let lt = self.lifetime_for(&info, mode);
1011            self.rustdoc(docs);
1012            self.push_str(&format!("pub type {}", name));
1013            self.print_generics(lt);
1014            self.push_str(" = ");
1015            self.print_list(ty, mode);
1016            self.push_str(";\n");
1017        }
1018    }
1019
1020    fn param_name(&self, ty: TypeId) -> String {
1021        let info = self.info(ty);
1022        let name = to_upper_camel_case(self.resolve().types[ty].name.as_ref().unwrap());
1023        if self.uses_two_names(&info) {
1024            format!("{}Param", name)
1025        } else {
1026            name
1027        }
1028    }
1029
1030    fn result_name(&self, ty: TypeId) -> String {
1031        let info = self.info(ty);
1032        let name = to_upper_camel_case(self.resolve().types[ty].name.as_ref().unwrap());
1033        if self.uses_two_names(&info) {
1034            format!("{}Result", name)
1035        } else if self.is_exported_resource(ty) {
1036            format!("Own{name}")
1037        } else {
1038            name
1039        }
1040    }
1041
1042    fn uses_two_names(&self, info: &TypeInfo) -> bool {
1043        // Types are only duplicated if explicitly requested ...
1044        matches!(
1045            self.ownership(),
1046            Ownership::Borrowing {
1047                duplicate_if_necessary: true
1048            }
1049        )
1050            // ... and if they're both used in a borrowed/owned context
1051            && info.borrowed
1052            && info.owned
1053            // ... and they have a list ...
1054            && info.has_list
1055            // ... and if there's NOT an `own` handle since those are always
1056            // done by ownership.
1057            && !info.has_own_handle
1058    }
1059
1060    fn lifetime_for(&self, info: &TypeInfo, mode: TypeMode) -> Option<&'static str> {
1061        let lt = match mode {
1062            TypeMode::AllBorrowed(s) | TypeMode::LeafBorrowed(s) | TypeMode::HandlesBorrowed(s) => {
1063                s
1064            }
1065            TypeMode::Owned => return None,
1066        };
1067        if info.has_borrow_handle {
1068            return Some(lt);
1069        }
1070        if matches!(self.ownership(), Ownership::Owning) {
1071            return None;
1072        }
1073        // No lifetimes needed unless this has a list.
1074        if !info.has_list {
1075            return None;
1076        }
1077        // If two names are used then this type will have an owned and a
1078        // borrowed copy and the borrowed copy is being used, so it needs a
1079        // lifetime. Otherwise if it's only borrowed and not owned then this can
1080        // also use a lifetime since it's not needed in two contexts and only
1081        // the borrowed version of the structure was generated.
1082        if self.uses_two_names(info) || (info.borrowed && !info.owned) {
1083            Some(lt)
1084        } else {
1085            None
1086        }
1087    }
1088}
1089
1090#[derive(Default)]
1091pub struct FnSig {
1092    pub async_: bool,
1093    pub unsafe_: bool,
1094    pub private: bool,
1095    pub use_item_name: bool,
1096    pub generics: Option<String>,
1097    pub self_arg: Option<String>,
1098    pub self_is_first_param: bool,
1099}
1100
1101pub trait RustFunctionGenerator {
1102    fn push_str(&mut self, s: &str);
1103    fn tmp(&mut self) -> usize;
1104    fn rust_gen(&self) -> &dyn RustGenerator;
1105    fn lift_lower(&self) -> LiftLower;
1106
1107    fn let_results(&mut self, amt: usize, results: &mut Vec<String>) {
1108        match amt {
1109            0 => {}
1110            1 => {
1111                let tmp = self.tmp();
1112                let res = format!("result{}", tmp);
1113                self.push_str("let ");
1114                self.push_str(&res);
1115                results.push(res);
1116                self.push_str(" = ");
1117            }
1118            n => {
1119                let tmp = self.tmp();
1120                self.push_str("let (");
1121                for i in 0..n {
1122                    let arg = format!("result{}_{}", tmp, i);
1123                    self.push_str(&arg);
1124                    self.push_str(",");
1125                    results.push(arg);
1126                }
1127                self.push_str(") = ");
1128            }
1129        }
1130    }
1131
1132    fn record_lower(
1133        &mut self,
1134        id: TypeId,
1135        record: &Record,
1136        operand: &str,
1137        results: &mut Vec<String>,
1138    ) {
1139        let tmp = self.tmp();
1140        self.push_str("let ");
1141        let name = self.typename_lower(id);
1142        self.push_str(&name);
1143        self.push_str("{ ");
1144        for field in record.fields.iter() {
1145            let name = to_rust_ident(&field.name);
1146            let arg = format!("{}{}", name, tmp);
1147            self.push_str(&name);
1148            self.push_str(":");
1149            self.push_str(&arg);
1150            self.push_str(", ");
1151            results.push(arg);
1152        }
1153        self.push_str("} = ");
1154        self.push_str(operand);
1155        self.push_str(";\n");
1156    }
1157
1158    fn record_lift(
1159        &mut self,
1160        id: TypeId,
1161        ty: &Record,
1162        operands: &[String],
1163        results: &mut Vec<String>,
1164    ) {
1165        let mut result = self.typename_lift(id);
1166        result.push_str("{\n");
1167        for (field, val) in ty.fields.iter().zip(operands) {
1168            result.push_str(&to_rust_ident(&field.name));
1169            result.push_str(": ");
1170            result.push_str(&val);
1171            result.push_str(",\n");
1172        }
1173        result.push_str("}");
1174        results.push(result);
1175    }
1176
1177    fn tuple_lower(&mut self, tuple: &Tuple, operand: &str, results: &mut Vec<String>) {
1178        let tmp = self.tmp();
1179        self.push_str("let (");
1180        for i in 0..tuple.types.len() {
1181            let arg = format!("t{}_{}", tmp, i);
1182            self.push_str(&arg);
1183            self.push_str(", ");
1184            results.push(arg);
1185        }
1186        self.push_str(") = ");
1187        self.push_str(operand);
1188        self.push_str(";\n");
1189    }
1190
1191    fn tuple_lift(&mut self, operands: &[String], results: &mut Vec<String>) {
1192        if operands.len() == 1 {
1193            results.push(format!("({},)", operands[0]));
1194        } else {
1195            results.push(format!("({})", operands.join(", ")));
1196        }
1197    }
1198
1199    fn typename_lower(&self, id: TypeId) -> String {
1200        let owned = match self.lift_lower() {
1201            LiftLower::LowerArgsLiftResults => false,
1202            LiftLower::LiftArgsLowerResults => true,
1203        };
1204        self.rust_gen().type_path(id, owned)
1205    }
1206
1207    fn typename_lift(&self, id: TypeId) -> String {
1208        self.rust_gen().type_path(id, true)
1209    }
1210}
1211
1212pub fn to_rust_ident(name: &str) -> String {
1213    match name {
1214        // Escape Rust keywords.
1215        // Source: https://doc.rust-lang.org/reference/keywords.html
1216        "as" => "as_".into(),
1217        "break" => "break_".into(),
1218        "const" => "const_".into(),
1219        "continue" => "continue_".into(),
1220        "crate" => "crate_".into(),
1221        "else" => "else_".into(),
1222        "enum" => "enum_".into(),
1223        "extern" => "extern_".into(),
1224        "false" => "false_".into(),
1225        "fn" => "fn_".into(),
1226        "for" => "for_".into(),
1227        "if" => "if_".into(),
1228        "impl" => "impl_".into(),
1229        "in" => "in_".into(),
1230        "let" => "let_".into(),
1231        "loop" => "loop_".into(),
1232        "match" => "match_".into(),
1233        "mod" => "mod_".into(),
1234        "move" => "move_".into(),
1235        "mut" => "mut_".into(),
1236        "pub" => "pub_".into(),
1237        "ref" => "ref_".into(),
1238        "return" => "return_".into(),
1239        "self" => "self_".into(),
1240        "static" => "static_".into(),
1241        "struct" => "struct_".into(),
1242        "super" => "super_".into(),
1243        "trait" => "trait_".into(),
1244        "true" => "true_".into(),
1245        "type" => "type_".into(),
1246        "unsafe" => "unsafe_".into(),
1247        "use" => "use_".into(),
1248        "where" => "where_".into(),
1249        "while" => "while_".into(),
1250        "async" => "async_".into(),
1251        "await" => "await_".into(),
1252        "dyn" => "dyn_".into(),
1253        "abstract" => "abstract_".into(),
1254        "become" => "become_".into(),
1255        "box" => "box_".into(),
1256        "do" => "do_".into(),
1257        "final" => "final_".into(),
1258        "macro" => "macro_".into(),
1259        "override" => "override_".into(),
1260        "priv" => "priv_".into(),
1261        "typeof" => "typeof_".into(),
1262        "unsized" => "unsized_".into(),
1263        "virtual" => "virtual_".into(),
1264        "yield" => "yield_".into(),
1265        "try" => "try_".into(),
1266        s => s.to_snake_case(),
1267    }
1268}
1269
1270pub fn to_upper_camel_case(name: &str) -> String {
1271    match name {
1272        // The name "Guest" is reserved for traits generated by exported
1273        // interfaces, so remap types defined in wit to something else.
1274        "guest" => "Guest_".to_string(),
1275        s => s.to_upper_camel_case(),
1276    }
1277}
1278
1279pub fn wasm_type(ty: WasmType) -> &'static str {
1280    match ty {
1281        WasmType::I32 => "i32",
1282        WasmType::I64 => "i64",
1283        WasmType::F32 => "f32",
1284        WasmType::F64 => "f64",
1285    }
1286}
1287
1288pub fn int_repr(repr: Int) -> &'static str {
1289    match repr {
1290        Int::U8 => "u8",
1291        Int::U16 => "u16",
1292        Int::U32 => "u32",
1293        Int::U64 => "u64",
1294    }
1295}
1296
1297pub fn bitcast(casts: &[Bitcast], operands: &[String], results: &mut Vec<String>) {
1298    for (cast, operand) in casts.iter().zip(operands) {
1299        results.push(match cast {
1300            Bitcast::None => operand.clone(),
1301            Bitcast::I32ToI64 => format!("i64::from({})", operand),
1302            Bitcast::F32ToI32 => format!("({}).to_bits() as i32", operand),
1303            Bitcast::F64ToI64 => format!("({}).to_bits() as i64", operand),
1304            Bitcast::I64ToI32 => format!("{} as i32", operand),
1305            Bitcast::I32ToF32 => format!("f32::from_bits({} as u32)", operand),
1306            Bitcast::I64ToF64 => format!("f64::from_bits({} as u64)", operand),
1307            Bitcast::F32ToI64 => format!("i64::from(({}).to_bits())", operand),
1308            Bitcast::I64ToF32 => format!("f32::from_bits({} as u32)", operand),
1309        });
1310    }
1311}
1312
1313pub enum RustFlagsRepr {
1314    U8,
1315    U16,
1316    U32,
1317    U64,
1318    U128,
1319}
1320
1321impl RustFlagsRepr {
1322    pub fn new(f: &Flags) -> RustFlagsRepr {
1323        match f.repr() {
1324            FlagsRepr::U8 => RustFlagsRepr::U8,
1325            FlagsRepr::U16 => RustFlagsRepr::U16,
1326            FlagsRepr::U32(1) => RustFlagsRepr::U32,
1327            FlagsRepr::U32(2) => RustFlagsRepr::U64,
1328            FlagsRepr::U32(3 | 4) => RustFlagsRepr::U128,
1329            FlagsRepr::U32(n) => panic!("unsupported number of flags: {}", n * 32),
1330        }
1331    }
1332}
1333
1334impl fmt::Display for RustFlagsRepr {
1335    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1336        match self {
1337            RustFlagsRepr::U8 => "u8".fmt(f),
1338            RustFlagsRepr::U16 => "u16".fmt(f),
1339            RustFlagsRepr::U32 => "u32".fmt(f),
1340            RustFlagsRepr::U64 => "u64".fmt(f),
1341            RustFlagsRepr::U128 => "u128".fmt(f),
1342        }
1343    }
1344}
1345
1346pub fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId {
1347    loop {
1348        match &resolve.types[id].kind {
1349            TypeDefKind::Type(Type::Id(that_id)) => id = *that_id,
1350            _ => break id,
1351        }
1352    }
1353}