#![feature(extend_one, let_chains, anonymous_lifetime_in_impl_trait, extract_if)]
use proc_macro::TokenStream;
use quote::{format_ident, quote_spanned};
use std::collections::HashMap;
use syn::{parse_macro_input, spanned::Spanned, ItemEnum};
use util::GATES_PARSER;
mod enums;
mod generics;
mod handle;
mod plugin_interface;
mod util;
#[proc_macro_attribute]
pub fn io_plugin(attribute_data: TokenStream, input: TokenStream) -> TokenStream {
let gates = GATES_PARSER
.captures_iter(&attribute_data.to_string())
.filter_map(|gate| {
Some((
gate.get(1)?.as_str().to_owned(),
gate.get(2)?.as_str().to_owned(),
))
})
.collect::<HashMap<_, _>>();
let mut input = parse_macro_input!(input as ItemEnum);
if let Some(lifetime) = input.generics.lifetimes().last() {
return quote_spanned!(lifetime.span()=>compile_error!("lifetimes are not supported in `io_plugin`");).into();
}
input.ident = format_ident!("{}", input.ident.to_string().trim_start_matches("_"));
let (message, response, response_impl) = enums::split_enum(&mut input);
for ty in input.generics.type_params_mut() {
ty.default = None;
}
#[allow(unused_variables)]
let handle = handle::generate_handle(
input.clone(),
message.clone(),
response.clone(),
gates.clone(),
);
let plugin_interface = plugin_interface::generate_trait(
input.clone(),
message.clone(),
response.clone(),
gates.clone(),
);
quote_spanned!(message.span()=>
#message
#response
#response_impl
#plugin_interface
#handle
)
.into()
}
#[proc_macro_attribute]
pub fn handle_doc(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn plugin_trait_doc(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn message_attributes(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn response_attributes(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}