paperless_api_macros/
lib.rs1mod derive_base;
2mod repr_serde;
3
4use proc_macro::TokenStream;
5use quote::{format_ident, quote};
6use syn::{DeriveInput, parse_macro_input};
7
8use crate::derive_base::BaseStruct;
9
10#[proc_macro_derive(CreateDto, attributes(dto, api_info))]
12pub fn derive_create_dto(input: TokenStream) -> TokenStream {
13 let input = parse_macro_input!(input as DeriveInput);
15 let input_struct = match BaseStruct::try_from(input) {
16 Ok(val) => val,
17 Err(e) => return e.to_compile_error().into(),
18 };
19
20 let new_struct_name = format_ident!("Create{}", input_struct.name);
22 let new_struct = input_struct.generate_new_struct(&new_struct_name, false);
23
24 let id_type_name = input_struct.id_type;
25 let id_type_name = quote!(crate::id::#id_type_name);
26
27 let endpoint = input_struct.endpoint.clone();
28 let name = input_struct.name;
29
30 TokenStream::from(quote! {
32 #new_struct
33
34 #[automatically_derived]
35 impl crate::dto::CreateDto for #new_struct_name {
36 type Id = #id_type_name;
37 type BaseType = #name;
38
39 fn endpoint() -> &'static str {
40 #endpoint
41 }
42 }
43 })
44}
45
46#[proc_macro_derive(UpdateDto, attributes(dto, api_info))]
48pub fn derive_update_dto(input: TokenStream) -> TokenStream {
49 let input = parse_macro_input!(input as DeriveInput);
51 let input_struct = match BaseStruct::try_from(input) {
52 Ok(val) => val,
53 Err(e) => return e.to_compile_error().into(),
54 };
55
56 let new_struct_name = format_ident!("Update{}", input_struct.name);
58 let new_struct = input_struct.generate_new_struct(&new_struct_name, true);
59
60 let id_type_name = input_struct.id_type;
61 let id_type_name = quote!(crate::id::#id_type_name);
62
63 let endpoint = input_struct.endpoint.clone();
64 let name = input_struct.name;
65
66 TokenStream::from(quote! {
68 #new_struct
69
70 #[automatically_derived]
71 impl crate::dto::UpdateDto for #new_struct_name {
72 type Id = #id_type_name;
73 type BaseType = #name;
74
75 fn endpoint() -> &'static str {
76 #endpoint
77 }
78 }
79 })
80}
81
82#[proc_macro_derive(Item, attributes(dto, api_info))]
84pub fn derive_item_trait(input: TokenStream) -> TokenStream {
85 let input = parse_macro_input!(input as DeriveInput);
87 let input_struct = match BaseStruct::try_from(input) {
88 Ok(val) => val,
89 Err(e) => return e.to_compile_error().into(),
90 };
91
92 let id_type_name = format_ident!("{}Id", input_struct.name);
93 let id_type_name = quote!(crate::id::#id_type_name);
94
95 let endpoint = input_struct.endpoint.clone();
96 let name = input_struct.name;
97
98 TokenStream::from(quote! {
100 #[automatically_derived]
101 impl crate::dto::Item for #name {
102 type Id = #id_type_name;
103 type BaseType = #name;
104
105 fn endpoint() -> &'static str {
106 #endpoint
107 }
108
109 fn id(&self) -> Self::Id {
110 self.id
111 }
112 }
113 })
114}
115
116#[proc_macro_derive(ReprSerde)]
122pub fn derive_repr_serde(input: TokenStream) -> TokenStream {
123 let input = parse_macro_input!(input as DeriveInput);
124
125 let repr_enum = match repr_serde::ReprEnum::try_from(input) {
126 Ok(val) => val,
127 Err(e) => return e.to_compile_error().into(),
128 };
129
130 TokenStream::from(repr_enum.generate())
131}