asset_derive_macro/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, DeriveInput, Generics, Ident, Result};
4
5mod attr;
6mod error;
7mod ident;
8mod variant;
9
10use attr::Attributes;
11use error::Error;
12use ident::Identifier;
13use variant::Variants;
14
15#[derive(Debug)]
24struct Assets<'a> {
25 name: &'a Ident,
26 generics: &'a Generics,
27 attrs: Attributes,
28 variants: Variants,
29}
30
31impl<'a> Assets<'a> {
32 pub fn from(input: &'a DeriveInput) -> Result<Self> {
36 Ok(Self {
37 name: &input.ident,
38 generics: &input.generics,
39 attrs: Attributes::from(&input.attrs)?,
40 variants: Variants::from(input)?,
41 })
42 }
43
44 pub fn build(self) -> TokenStream {
46 let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl();
47 let name = self.name;
48 let getters = self.variants.build_getters(&self.attrs);
49 let arms = self.variants.build_arms();
50 quote! {
51 impl #impl_generics #name #ty_generics #where_clause {
52 #(#getters)*
53 }
54
55 impl #impl_generics Asset for #name #ty_generics #where_clause {
56 fn fetch(&self) -> Vec<u8> {
57 match self {
58 #(#arms),*
59 }.to_vec()
60 }
61 fn fetch_static(&self) -> &'static [u8] {
62 match self {
63 #(#arms),*
64 }
65 }
66 }
67 }
68 .into()
69 }
70}
71
72#[proc_macro_derive(Asset, attributes(asset))]
78pub fn derive_asset(input: TokenStream) -> TokenStream {
79 impl_asset(&parse_macro_input!(input as DeriveInput))
80 .unwrap_or_else(|err| err.to_compile_error().into())
81}
82
83fn impl_asset(input: &DeriveInput) -> Result<TokenStream> {
87 Ok(Assets::from(input)?.build())
88}