1#![recursion_limit = "128"]
7
8extern crate proc_macro;
9extern crate proc_macro2;
10#[macro_use]
11extern crate quote;
12#[macro_use]
13extern crate syn;
14
15use proc_macro::TokenStream;
16use syn::{
17 parse::{Parse, ParseStream, Result},
18 DeriveInput, Path,
19};
20
21mod impl_saveload;
22
23#[proc_macro_derive(Component, attributes(storage))]
35pub fn component(input: TokenStream) -> TokenStream {
36 let ast = syn::parse(input).unwrap();
37 let gen = impl_component(&ast);
38 gen.into()
39}
40
41struct StorageAttribute {
42 storage: Path,
43}
44
45impl Parse for StorageAttribute {
46 fn parse(input: ParseStream) -> Result<Self> {
47 let content;
48 let _parenthesized_token = parenthesized!(content in input);
49
50 Ok(StorageAttribute {
51 storage: content.parse()?,
52 })
53 }
54}
55
56fn impl_component(ast: &DeriveInput) -> proc_macro2::TokenStream {
57 let name = &ast.ident;
58 let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
59
60 let storage = ast
61 .attrs
62 .iter()
63 .find(|attr| attr.path.segments[0].ident == "storage")
64 .map(|attr| {
65 syn::parse2::<StorageAttribute>(attr.tokens.clone())
66 .unwrap()
67 .storage
68 })
69 .unwrap_or_else(|| parse_quote!(DenseVecStorage));
70
71 quote! {
72 impl #impl_generics Component for #name #ty_generics #where_clause {
73 type Storage = #storage<Self>;
74 }
75 }
76}
77
78#[proc_macro_derive(ConvertSaveload)]
92pub fn saveload(input: TokenStream) -> TokenStream {
93 use impl_saveload::impl_saveload;
94 let mut ast = syn::parse(input).unwrap();
95
96 let gen = impl_saveload(&mut ast);
97 gen.into()
98}