1 pub mod config;
2 mod error_transform;
3 mod funcs;
4 mod lifetimes;
5 mod module_trait;
6 mod names;
7 mod types;
8 
9 use proc_macro2::TokenStream;
10 use quote::quote;
11 
12 use lifetimes::anon_lifetime;
13 
14 pub use config::Config;
15 pub use error_transform::{ErrorTransform, UserErrorType};
16 pub use funcs::define_func;
17 pub use module_trait::define_module_trait;
18 pub use names::Names;
19 pub use types::define_datatype;
20 
generate(doc: &witx::Document, names: &Names, errs: &ErrorTransform) -> TokenStream21 pub fn generate(doc: &witx::Document, names: &Names, errs: &ErrorTransform) -> TokenStream {
22     // TODO at some point config should grow more ability to configure name
23     // overrides.
24     let rt = names.runtime_mod();
25 
26     let types = doc.typenames().map(|t| define_datatype(&names, &t));
27 
28     let guest_error_methods = doc.error_types().map(|t| {
29         let typename = names.type_ref(&t, anon_lifetime());
30         let err_method = names.guest_error_conversion_method(&t);
31         quote!(fn #err_method(&self, e: #rt::GuestError) -> #typename;)
32     });
33     let guest_error_conversion = quote! {
34         pub trait GuestErrorConversion {
35             #(#guest_error_methods)*
36         }
37     };
38 
39     let user_error_methods = errs.iter().map(|errtype| {
40         let abi_typename = names.type_ref(&errtype.abi_type(), anon_lifetime());
41         let user_typename = errtype.typename();
42         let methodname = names.user_error_conversion_method(&errtype);
43         quote!(fn #methodname(&self, e: super::#user_typename) -> #abi_typename;)
44     });
45     let user_error_conversion = quote! {
46         pub trait UserErrorConversion {
47             #(#user_error_methods)*
48         }
49     };
50     let modules = doc.modules().map(|module| {
51         let modname = names.module(&module.name);
52         let fs = module
53             .funcs()
54             .map(|f| define_func(&names, &module, &f, &errs));
55         let modtrait = define_module_trait(&names, &module, &errs);
56         let ctx_type = names.ctx_type();
57         quote!(
58             pub mod #modname {
59                 use super::#ctx_type;
60                 use super::types::*;
61                 #(#fs)*
62 
63                 #modtrait
64             }
65         )
66     });
67 
68     quote!(
69         pub mod types {
70             #(#types)*
71             #guest_error_conversion
72             #user_error_conversion
73         }
74         #(#modules)*
75     )
76 }
77 
generate_metadata(doc: &witx::Document, names: &Names) -> TokenStream78 pub fn generate_metadata(doc: &witx::Document, names: &Names) -> TokenStream {
79     let rt = names.runtime_mod();
80     let doc_text = &format!("{}", doc);
81     quote! {
82         pub mod metadata {
83             pub const DOC_TEXT: &str = #doc_text;
84             pub fn document() -> #rt::witx::Document {
85                 #rt::witx::parse(DOC_TEXT).unwrap()
86             }
87         }
88     }
89 }
90