1#![recursion_limit = "512"]
7
8extern crate proc_macro;
9#[macro_use]
10extern crate proc_macro_error2;
11
12#[cfg(feature = "actix")]
13#[macro_use]
14mod actix;
15#[cfg(feature = "v2")]
16mod core;
17
18use proc_macro::TokenStream;
19use quote::quote;
20use syn::{
21 parse::{Parse, ParseStream},
22 punctuated::Punctuated,
23 spanned::Spanned,
24 token::Comma,
25 DeriveInput, NestedMeta,
26};
27
28#[cfg(feature = "v2")]
33#[proc_macro_attribute]
34pub fn api_v2_schema_struct(_attr: TokenStream, input: TokenStream) -> TokenStream {
35 self::core::emit_v2_schema_struct(input)
36}
37
38#[cfg(feature = "actix")]
40#[proc_macro_error]
41#[proc_macro_attribute]
42pub fn api_v2_operation(attr: TokenStream, input: TokenStream) -> TokenStream {
43 self::actix::emit_v2_operation(attr, input)
44}
45
46#[cfg(feature = "actix")]
48#[proc_macro_error]
49#[proc_macro_derive(Apiv2Schema, attributes(openapi))]
50pub fn api_v2_schema(input: TokenStream) -> TokenStream {
51 self::actix::emit_v2_definition(input)
52}
53
54#[cfg(feature = "actix")]
56#[proc_macro_error]
57#[proc_macro_derive(Apiv2Security, attributes(openapi))]
58pub fn api_v2_security(input: TokenStream) -> TokenStream {
59 self::actix::emit_v2_security(input)
60}
61
62#[cfg(feature = "actix")]
64#[proc_macro_error]
65#[proc_macro_derive(Apiv2Header, attributes(openapi))]
66pub fn api_v2_header(input: TokenStream) -> TokenStream {
67 self::actix::emit_v2_header(input)
68}
69
70#[cfg(feature = "actix")]
73#[proc_macro_error]
74#[proc_macro_attribute]
75pub fn api_v2_errors(attrs: TokenStream, input: TokenStream) -> TokenStream {
76 self::actix::emit_v2_errors(attrs, input)
77}
78
79#[cfg(feature = "actix")]
82#[proc_macro_error]
83#[proc_macro_attribute]
84pub fn api_v2_errors_overlay(attrs: TokenStream, input: TokenStream) -> TokenStream {
85 self::actix::emit_v2_errors_overlay(attrs, input)
86}
87
88#[allow(dead_code)]
90fn span_error_with_msg<T: Spanned>(it: &T, msg: &str) -> TokenStream {
91 emit_error!(it.span().unwrap(), msg);
92 (quote! {}).into()
93}
94
95#[allow(dead_code)]
97fn expect_struct_or_enum(ts: TokenStream) -> Result<DeriveInput, TokenStream> {
98 syn::parse(ts).map_err(|e| {
99 emit_error!(
100 e.span().unwrap(),
101 "expected struct or enum for deriving schema."
102 );
103 quote!().into()
104 })
105}
106
107#[derive(Default)]
109struct MacroAttribute(#[allow(dead_code)] Punctuated<NestedMeta, Comma>);
110
111impl Parse for MacroAttribute {
112 fn parse(input: ParseStream) -> syn::Result<Self> {
113 Ok(MacroAttribute(input.call(Punctuated::parse_terminated)?))
114 }
115}
116
117#[cfg(feature = "actix")]
118fn parse_input_attrs(ts: TokenStream) -> MacroAttribute {
119 syn::parse(ts)
120 .map_err(|e| {
121 emit_warning!(
122 e.span().unwrap(),
123 "cannot parse proc-macro input attributes."
124 );
125 })
126 .ok()
127 .unwrap_or_default()
128}
129
130#[cfg(feature = "actix")]
131rest_methods! {
132 Get, get,
133 Post, post,
134 Put, put,
135 Delete, delete,
136 Patch, patch,
137 Head, head,
138}