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
use proc_macro2::TokenStream;
use quote::quote;

/// Deriver for the `Module` trait.
pub struct DeriveModule {
    /// Items specifying the module configuration.
    module_cfg: Vec<syn::ImplItem>,
}

impl DeriveModule {
    pub fn new() -> Box<Self> {
        Box::new(Self { module_cfg: vec![] })
    }
}

impl super::Deriver for DeriveModule {
    fn preprocess(&mut self, item: syn::ImplItem) -> Option<syn::ImplItem> {
        match item {
            syn::ImplItem::Type(ref ty) => {
                match ty.ident.to_string().as_str() {
                    "Error" | "Event" | "Parameters" => {
                        self.module_cfg.push(item);
                        None // Take the item.
                    }
                    _ => Some(item), // Return the item.
                }
            }
            syn::ImplItem::Const(ref cnst) => {
                match cnst.ident.to_string().as_str() {
                    "NAME" | "VERSION" => {
                        self.module_cfg.push(item);
                        None // Take the item.
                    }
                    _ => Some(item), // Return the item.
                }
            }
            _ => Some(item), // Return the item.
        }
    }

    fn derive(&mut self, generics: &syn::Generics, ty: &Box<syn::Type>) -> TokenStream {
        if self.module_cfg.is_empty() {
            return quote! {};
        }
        let module_cfg = &self.module_cfg;

        quote! {
            #[automatically_derived]
            impl #generics sdk::module::Module for #ty {
                #(#module_cfg)*
            }
        }
    }
}