use std::ffi::CString;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{ItemStruct, LitCStr, LitStr};
use crate::args::PluginArgs;
mod manifest;
mod plugin_init;
pub(crate) fn plugin(args: &PluginArgs, target: &ItemStruct) -> syn::Result<TokenStream2> {
let ty = &target.ident;
let name_lit = cstr_lit(&args.name)?;
let descr_lit = cstr_lit(&args.description)?;
let author_lit = cstr_lit(&args.author)?;
let manifest_module = manifest::manifest_module();
let manifest_statics = manifest::manifest_statics(
&name_lit,
&descr_lit,
&author_lit,
&args.version,
&args.license,
);
let plugin_init = plugin_init::plugin_init(ty, args.handlerton.as_ref());
Ok(quote! {
#target
#manifest_module
#manifest_statics
#plugin_init
})
}
fn cstr_lit(lit: &LitStr) -> syn::Result<LitCStr> {
let value = lit.value();
let cstring = CString::new(value).map_err(|_| {
syn::Error::new(
lit.span(),
"#[plugin] string literal must not contain a NUL byte",
)
})?;
Ok(LitCStr::new(&cstring, lit.span()))
}