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 #[automatically_derived]
28 impl crate::dto::CreateDtoObject for #new_struct_name {}
29 })
30}
31
32#[proc_macro_derive(UpdateDto, attributes(dto, api_info))]
34pub fn derive_update_dto(input: TokenStream) -> TokenStream {
35 let input = parse_macro_input!(input as DeriveInput);
37 let input_struct = match BaseStruct::try_from(input) {
38 Ok(val) => val,
39 Err(e) => return e.to_compile_error().into(),
40 };
41
42 let new_struct_name = format_ident!("Update{}", input_struct.name);
44 let new_struct = input_struct.generate_new_struct(&new_struct_name, true);
45
46 TokenStream::from(quote! {
48 #new_struct
49
50 #[automatically_derived]
51 impl crate::dto::UpdateDtoObject for #new_struct_name {}
52 })
53}
54
55#[proc_macro_derive(Item, attributes(dto, api_info))]
57pub fn derive_item_trait(input: TokenStream) -> TokenStream {
58 let input = parse_macro_input!(input as DeriveInput);
60 let input_struct = match ItemStruct::try_from(input) {
61 Ok(val) => val,
62 Err(e) => return e.to_compile_error().into(),
63 };
64
65 let update_dto = format_ident!("Update{}", input_struct.base_struct.name);
66 let create_dto = format_ident!("Create{}", input_struct.base_struct.name);
67 let id_type_name = format_ident!("{}Id", input_struct.base_struct.name);
68 let id_type_name = quote!(crate::id::#id_type_name);
69
70 let endpoint = input_struct.endpoint.clone();
71 let name = input_struct.base_struct.name;
72
73 TokenStream::from(quote! {
75 #[automatically_derived]
76 impl crate::dto::Item for #name {
77 type Id = #id_type_name;
78 type BaseType = #name;
79 type CreateDto = #create_dto;
80 type UpdateDto = #update_dto;
81
82 fn endpoint() -> &'static str {
83 #endpoint
84 }
85
86 fn id(&self) -> Self::Id {
87 self.id
88 }
89 }
90 })
91}