1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#![feature(extend_one, let_chains, anonymous_lifetime_in_impl_trait)]

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 handle_interface;
mod plugin_interface;
mod util;

/// Generate a plugin-interface, based on an enum definition for its' operations
/// 
/// The variants must be [`serde::Serialize`] + [`serde::Deserialize`].
#[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);

    input.ident = format_ident!("{}", input.ident.to_string().trim_start_matches("_"));

    let (message, response, response_impl) = enums::split_enum(&input);
    let host_interface = handle_interface::generate_trait(
        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
    #host_interface
    #plugin_interface
    )
    .into()
}

/// Allows customising the documentation of the handle generated by [`io_plugin`]
#[proc_macro_attribute]
pub fn handle_doc(_attr: TokenStream, item: TokenStream) -> TokenStream {
    item
}

/// Allows customising the documentation of the plugin trait generated by [`io_plugin`]
#[proc_macro_attribute]
pub fn plugin_trait_doc(_attr: TokenStream, item: TokenStream) -> TokenStream {
    item
}