gotham_restful_derive/
lib.rs

1#![warn(missing_debug_implementations, rust_2018_idioms)]
2#![deny(rustdoc::broken_intra_doc_links)]
3#![forbid(unsafe_code)]
4
5use proc_macro::TokenStream;
6use proc_macro2::TokenStream as TokenStream2;
7use syn::{
8	parse::{Parse, ParseStream},
9	parse_macro_input,
10	punctuated::Punctuated,
11	DeriveInput, Meta, Result, Token
12};
13
14mod util;
15
16mod endpoint;
17use endpoint::{expand_endpoint, EndpointType};
18
19mod from_body;
20use from_body::expand_from_body;
21
22mod request_body;
23use request_body::expand_request_body;
24
25mod resource;
26use resource::expand_resource;
27
28mod resource_error;
29use resource_error::expand_resource_error;
30
31mod private_openapi_trait;
32use private_openapi_trait::expand_private_openapi_trait;
33
34struct AttributeArgs(Punctuated<Meta, Token![,]>);
35
36impl Parse for AttributeArgs {
37	fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
38		Ok(Self(Punctuated::parse_terminated(input)?))
39	}
40}
41
42#[inline]
43fn print_tokens(tokens: TokenStream2) -> TokenStream {
44	// eprintln!("{tokens}");
45	tokens.into()
46}
47
48#[inline]
49fn expand_derive<F>(input: TokenStream, expand: F) -> TokenStream
50where
51	F: FnOnce(DeriveInput) -> Result<TokenStream2>
52{
53	print_tokens(expand(parse_macro_input!(input)).unwrap_or_else(|err| err.to_compile_error()))
54}
55
56#[inline]
57fn expand_macro<F, A, I>(attrs: TokenStream, item: TokenStream, expand: F) -> TokenStream
58where
59	F: FnOnce(A, I) -> Result<TokenStream2>,
60	A: Parse,
61	I: Parse
62{
63	print_tokens(
64		expand(parse_macro_input!(attrs), parse_macro_input!(item))
65			.unwrap_or_else(|err| err.to_compile_error())
66	)
67}
68
69#[proc_macro_derive(FromBody)]
70pub fn derive_from_body(input: TokenStream) -> TokenStream {
71	expand_derive(input, expand_from_body)
72}
73
74#[proc_macro_derive(RequestBody, attributes(supported_types))]
75pub fn derive_request_body(input: TokenStream) -> TokenStream {
76	expand_derive(input, expand_request_body)
77}
78
79#[proc_macro_derive(Resource, attributes(resource))]
80pub fn derive_resource(input: TokenStream) -> TokenStream {
81	expand_derive(input, expand_resource)
82}
83
84#[proc_macro_derive(ResourceError, attributes(display, from, status))]
85pub fn derive_resource_error(input: TokenStream) -> TokenStream {
86	expand_derive(input, expand_resource_error)
87}
88
89#[proc_macro_attribute]
90pub fn endpoint(attr: TokenStream, item: TokenStream) -> TokenStream {
91	expand_macro(attr, item, |attr, item| {
92		expand_endpoint(EndpointType::custom(), attr, item)
93	})
94}
95
96#[proc_macro_attribute]
97pub fn read_all(attr: TokenStream, item: TokenStream) -> TokenStream {
98	expand_macro(attr, item, |attr, item| {
99		expand_endpoint(EndpointType::ReadAll, attr, item)
100	})
101}
102
103#[proc_macro_attribute]
104pub fn read(attr: TokenStream, item: TokenStream) -> TokenStream {
105	expand_macro(attr, item, |attr, item| {
106		expand_endpoint(EndpointType::Read, attr, item)
107	})
108}
109
110#[proc_macro_attribute]
111pub fn search(attr: TokenStream, item: TokenStream) -> TokenStream {
112	expand_macro(attr, item, |attr, item| {
113		expand_endpoint(EndpointType::Search, attr, item)
114	})
115}
116
117#[proc_macro_attribute]
118pub fn create(attr: TokenStream, item: TokenStream) -> TokenStream {
119	expand_macro(attr, item, |attr, item| {
120		expand_endpoint(EndpointType::Create, attr, item)
121	})
122}
123
124#[proc_macro_attribute]
125pub fn update_all(attr: TokenStream, item: TokenStream) -> TokenStream {
126	expand_macro(attr, item, |attr, item| {
127		expand_endpoint(EndpointType::UpdateAll, attr, item)
128	})
129}
130
131#[proc_macro_attribute]
132pub fn update(attr: TokenStream, item: TokenStream) -> TokenStream {
133	expand_macro(attr, item, |attr, item| {
134		expand_endpoint(EndpointType::Update, attr, item)
135	})
136}
137
138#[proc_macro_attribute]
139pub fn delete_all(attr: TokenStream, item: TokenStream) -> TokenStream {
140	expand_macro(attr, item, |attr, item| {
141		expand_endpoint(EndpointType::DeleteAll, attr, item)
142	})
143}
144
145#[proc_macro_attribute]
146pub fn delete(attr: TokenStream, item: TokenStream) -> TokenStream {
147	expand_macro(attr, item, |attr, item| {
148		expand_endpoint(EndpointType::Delete, attr, item)
149	})
150}
151
152/// PRIVATE MACRO - DO NOT USE
153#[doc(hidden)]
154#[proc_macro_attribute]
155pub fn _private_openapi_trait(attr: TokenStream, item: TokenStream) -> TokenStream {
156	expand_macro(attr, item, expand_private_openapi_trait)
157}