paperless_api_macros/
lib.rs1mod derive_base;
2
3use proc_macro::TokenStream;
4use quote::{format_ident, quote};
5use syn::{DeriveInput, parse_macro_input};
6
7use crate::derive_base::{BaseStruct, ItemStruct};
8
9#[proc_macro_derive(CreateDto, attributes(dto, api_info))]
11pub fn derive_create_dto(input: TokenStream) -> TokenStream {
12 let input = parse_macro_input!(input as DeriveInput);
14 let input_struct = match BaseStruct::try_from(input) {
15 Ok(val) => val,
16 Err(e) => return e.to_compile_error().into(),
17 };
18
19 let new_struct_name = format_ident!("Create{}", input_struct.name);
21 let new_struct = input_struct.generate_new_struct(&new_struct_name, false);
22
23 TokenStream::from(quote! {
25 #new_struct
26
27 impl crate::dto::CreateDtoObject for #new_struct_name {}
28 })
29}
30
31#[proc_macro_derive(UpdateDto, attributes(dto, api_info))]
33pub fn derive_update_dto(input: TokenStream) -> TokenStream {
34 let input = parse_macro_input!(input as DeriveInput);
36 let input_struct = match BaseStruct::try_from(input) {
37 Ok(val) => val,
38 Err(e) => return e.to_compile_error().into(),
39 };
40
41 let new_struct_name = format_ident!("Update{}", input_struct.name);
43 let new_struct = input_struct.generate_new_struct(&new_struct_name, true);
44
45 TokenStream::from(quote! {
47 #new_struct
48
49 impl crate::dto::UpdateDtoObject for #new_struct_name {}
50 })
51}
52
53#[proc_macro_derive(Item, attributes(dto, api_info))]
55pub fn derive_item_trait(input: TokenStream) -> TokenStream {
56 let input = parse_macro_input!(input as DeriveInput);
58 let input_struct = match ItemStruct::try_from(input) {
59 Ok(val) => val,
60 Err(e) => return e.to_compile_error().into(),
61 };
62
63 let update_dto = format_ident!("Update{}", input_struct.base_struct.name);
64 let create_dto = format_ident!("Create{}", input_struct.base_struct.name);
65 let id_type_name = format_ident!("{}Id", input_struct.base_struct.name);
66 let id_type_name = quote!(crate::id::#id_type_name);
67
68 let endpoint = input_struct.endpoint.clone();
69 let name = input_struct.base_struct.name;
70
71 TokenStream::from(quote! {
73 impl crate::dto::Item for #name {
74 type Id = #id_type_name;
75 type BaseType = #name;
76 type CreateDto = #create_dto;
77 type UpdateDto = #update_dto;
78
79 fn endpoint() -> &'static str {
80 #endpoint
81 }
82
83 fn id(&self) -> Self::Id {
84 self.id
85 }
86 }
87 })
88}