conniecs_derive/
lib.rs

1#[macro_use]
2extern crate quote;
3#[macro_use]
4extern crate syn;
5
6extern crate proc_macro;
7extern crate proc_macro2;
8
9use proc_macro::TokenStream;
10use quote::TokenStreamExt;
11use syn::DeriveInput;
12
13mod aspect;
14mod components;
15mod services;
16mod system;
17mod systems;
18
19#[proc_macro_derive(Aspect, attributes(aspect, components))]
20pub fn derive_aspect(input: TokenStream) -> TokenStream {
21    // Parse the string representation
22    let ast = parse_macro_input!(input as DeriveInput);
23
24    // Build the impl
25    let result = aspect::impl_aspect(ast);
26
27    //panic!("{}", result);
28
29    result.into()
30}
31
32#[proc_macro_derive(ComponentManager, attributes(hot, cold))]
33pub fn derive_components(input: TokenStream) -> TokenStream {
34    // Parse the string representation
35    let ast = parse_macro_input!(input as DeriveInput);
36
37    // Build the impl
38    let result = components::impl_components(ast);
39
40    // Return the generated impl
41    result.into()
42}
43
44#[proc_macro_derive(ServiceManager)]
45pub fn derive_services(input: TokenStream) -> TokenStream {
46    // Parse the string representation
47    let ast = parse_macro_input!(input as DeriveInput);
48
49    // Build the impl
50    let result = services::impl_services(ast);
51
52    // Return the generated impl
53    result.into()
54}
55
56#[proc_macro_derive(
57    System,
58    attributes(
59        data,
60        system_type,
61        process,
62        aspect,
63        aspect_a,
64        aspect_b,
65        interval,
66        timed_interval,
67        activated,
68        reactivated,
69        deactivated
70    )
71)]
72pub fn derive_system(input: TokenStream) -> TokenStream {
73    // Parse the string representation
74    let ast = parse_macro_input!(input as DeriveInput);
75
76    // Build the impl
77    let result = system::impl_system(ast);
78
79    // Return the generated impl
80    result.into()
81}
82
83#[proc_macro_derive(SystemManager, attributes(data, passive))]
84pub fn derive_systems(input: TokenStream) -> TokenStream {
85    // Parse the string representation
86    let ast = parse_macro_input!(input as DeriveInput);
87
88    // Build the impl
89    let result = systems::impl_systems(ast);
90
91    // Return the generated impl
92    result.into()
93}
94
95fn improper_attr_format(attr: &str, module: &str) -> ! {
96    panic!(
97        "{} was not in the correct format. Please refer to the {} \
98         module documentation for more information.",
99        attr, module
100    )
101}
102
103fn read_path_item<F>(attr: &syn::Meta, fail: F) -> String
104where
105    F: FnOnce(),
106{
107    match attr {
108        syn::Meta::Word(word) => word.to_string(),
109        syn::Meta::List(list) => {
110            let items = &list.nested;
111            if items.len() != 1 {
112                fail();
113                unreachable!();
114            }
115
116            match items[0] {
117                syn::NestedMeta::Literal(syn::Lit::Str(ref value)) => value.value(),
118                syn::NestedMeta::Meta(syn::Meta::Word(ref word)) => word.to_string(),
119                _ => {
120                    fail();
121                    unreachable!();
122                }
123            }
124        }
125        syn::Meta::NameValue(syn::MetaNameValue {
126            lit: syn::Lit::Str(ref value),
127            ..
128        }) => value.value(),
129        _ => {
130            fail();
131            unreachable!();
132        }
133    }
134}
135
136fn quote_path(path: &str) -> proc_macro2::TokenStream {
137    let mut tokens = proc_macro2::TokenStream::new();
138    for (i, part) in path.split("::").enumerate() {
139        use proc_macro2::{Ident, Punct, Spacing, Span};
140        if i != 0 {
141            tokens.append_all(&[
142                Punct::new(':', Spacing::Joint),
143                Punct::new(':', Spacing::Joint),
144            ]);
145        }
146        if part.len() > 0 {
147            tokens.append(Ident::new(part, Span::call_site()));
148        }
149    }
150    tokens
151}