resource_fork_macros/
lib.rs1use darling::FromDeriveInput;
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{parse_macro_input, DeriveInput};
6
7#[derive(FromDeriveInput, Default)]
8#[darling(default, attributes(resource))]
9struct Opts {
10 #[darling(default)]
11 code: String,
12 include_size: Option<bool>,
13 include_id: Option<bool>,
14 include_name: Option<bool>,
15}
16
17#[proc_macro_derive(Resource, attributes(resource))]
41pub fn derive(input: TokenStream) -> TokenStream {
42 let input = parse_macro_input!(input);
43 let opts = Opts::from_derive_input(&input).expect("Wrong options");
44 let DeriveInput { ident, .. } = input;
45
46 let make_args = match (
47 opts.include_size.unwrap_or_default(),
48 opts.include_id.unwrap_or_default(),
49 opts.include_name.unwrap_or_default(),
50 ) {
51 (true, false, false) => quote! { (size, ) },
52 (true, true, false) => quote! { (size, id, ) },
53 (true, true, true) => quote! { (size, id, name) },
54 (true, false, true) => quote! { (size, name) },
55 (false, true, false) => quote! { ( id,) },
56 (false, true, true) => quote! { ( id, name) },
57 (false, false, true) => quote! { ( name,) },
58 (false, false, false) => quote! {()},
59 };
60 let code = opts.code;
61
62 let output = quote! {
63 impl<'a> ::resource_fork::ResourceReading for #ident {
64 const FOURCC: fourcc::FourCC = fourcc::fourcc!(#code);
65
66 fn from_slice(buffer: &[u8], id: u16, name: &str) -> std::result::Result<Self, ::resource_fork::Error>
67 where
68 Self: Sized,
69 {
70 use binrw::BinReaderExt;
71 let size: usize = buffer.len();
72 let mut reader = std::io::Cursor::new(buffer);
73 reader.read_be_args(#make_args).map_err(|e| e.into())
74 }
75 }
76 };
77 output.into()
78}