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