Path: blob/main/crates/wiggle/generate/src/lib.rs
1693 views
mod codegen_settings;1pub mod config;2mod funcs;3mod lifetimes;4mod module_trait;5pub mod names;6mod types;7pub mod wasmtime;89use heck::ToShoutySnakeCase;10use lifetimes::anon_lifetime;11use proc_macro2::{Literal, TokenStream};12use quote::quote;1314pub use codegen_settings::{CodegenSettings, ErrorType, UserErrorType};15pub use config::{Config, WasmtimeConfig};16pub use funcs::define_func;17pub use module_trait::define_module_trait;18pub use types::define_datatype;1920pub fn generate(doc: &witx::Document, settings: &CodegenSettings) -> TokenStream {21let types = doc22.typenames()23.map(|t| define_datatype(&t, settings.errors.for_name(&t)));2425let constants = doc.constants().map(|c| {26let name = quote::format_ident!(27"{}_{}",28c.ty.as_str().to_shouty_snake_case(),29c.name.as_str().to_shouty_snake_case()30);31let ty = names::type_(&c.ty);32let value = Literal::u64_unsuffixed(c.value);33quote! {34pub const #name: #ty = #value;35}36});3738let user_error_methods = settings.errors.iter().filter_map(|errtype| match errtype {39ErrorType::User(errtype) => {40let abi_typename = names::type_ref(&errtype.abi_type(), anon_lifetime());41let user_typename = errtype.typename();42let methodname = names::user_error_conversion_method(&errtype);43Some(quote! {44fn #methodname(&mut self, e: super::#user_typename)45-> wiggle::anyhow::Result<#abi_typename>;46})47}48ErrorType::Generated(_) => None,49});50let user_error_conversion = quote! {51pub trait UserErrorConversion {52#(#user_error_methods)*53}54};55let modules = doc.modules().map(|module| {56let modname = names::module(&module.name);57let fs = module.funcs().map(|f| define_func(&module, &f, &settings));58let modtrait = define_module_trait(&module, &settings);59let wasmtime = if settings.wasmtime {60crate::wasmtime::link_module(&module, None, &settings)61} else {62quote! {}63};64quote!(65pub mod #modname {66use super::types::*;67pub use super::types::UserErrorConversion;68#(#fs)*6970#modtrait7172#wasmtime73}74)75});7677quote!(78pub mod types {79use std::convert::TryFrom;8081#(#types)*82#(#constants)*83#user_error_conversion84}85#(#modules)*86)87}8889pub fn generate_metadata(doc: &witx::Document) -> TokenStream {90let doc_text = &format!("{doc}");91quote! {92pub mod metadata {93pub const DOC_TEXT: &str = #doc_text;94pub fn document() -> wiggle::witx::Document {95wiggle::witx::parse(DOC_TEXT).unwrap()96}97}98}99}100101102