#![feature(extend_one, let_chains, anonymous_lifetime_in_impl_trait, extract_if)]
use std::collections::HashMap;
use proc_macro::TokenStream;
use quote::{format_ident, quote_spanned};
use syn::{parse_macro_input, spanned::Spanned, ItemEnum};
use crate::{feature_gates::FeatureGates, util::generate_gate};
mod enums;
mod feature_gates;
mod generics;
mod handle;
mod plugin_interface;
mod util;
#[proc_macro_attribute]
pub fn io_plugin(attribute_data: TokenStream, input: TokenStream) -> TokenStream {
let gates = syn::parse::<FeatureGates>(attribute_data).ok();
let gates = gates.map(|g| g.hashmap()).unwrap_or(HashMap::new());
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(),
generate_gate(gates.get("handle")),
);
let (plugin_trait, main_loop_iteration) =
plugin_interface::generate_trait(input.clone(), message.clone(), response.clone());
let plugin_trait_gate = generate_gate(gates.get("plugin_trait"));
quote_spanned!(message.span()=>
#message
#response
#response_impl
#plugin_trait_gate
#plugin_trait
#plugin_trait_gate
#main_loop_iteration
#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
}