poem_openapi_derive/
lib.rs

1//! Macros for poem-openapi
2
3#![doc(html_favicon_url = "https://raw.githubusercontent.com/poem-web/poem/master/favicon.ico")]
4#![doc(html_logo_url = "https://raw.githubusercontent.com/poem-web/poem/master/logo.png")]
5#![forbid(unsafe_code)]
6#![deny(unreachable_pub)]
7
8#[macro_use]
9mod validators;
10
11mod api;
12mod common_args;
13mod r#enum;
14mod error;
15mod multipart;
16mod newtype;
17mod oauth_scopes;
18mod object;
19mod request;
20mod response;
21mod response_content;
22mod security_scheme;
23mod tags;
24mod union;
25mod utils;
26mod webhook;
27
28mod parameter_style;
29
30use darling::FromMeta;
31use proc_macro::TokenStream;
32use syn::{parse_macro_input, DeriveInput, ItemImpl, ItemTrait};
33
34macro_rules! parse_nested_meta {
35    ($ty:ty, $args:expr) => {{
36        let meta = match darling::ast::NestedMeta::parse_meta_list(proc_macro2::TokenStream::from(
37            $args,
38        )) {
39            Ok(v) => v,
40            Err(e) => {
41                return TokenStream::from(darling::Error::from(e).write_errors());
42            }
43        };
44
45        match <$ty>::from_list(&meta) {
46            Ok(object_args) => object_args,
47            Err(err) => return TokenStream::from(err.write_errors()),
48        }
49    }};
50}
51
52#[proc_macro_derive(Object, attributes(oai))]
53pub fn derive_object(input: TokenStream) -> TokenStream {
54    let args = parse_macro_input!(input as DeriveInput);
55    match object::generate(args) {
56        Ok(stream) => stream.into(),
57        Err(err) => err.write_errors().into(),
58    }
59}
60
61#[proc_macro_derive(Enum, attributes(oai))]
62pub fn derive_enum(input: TokenStream) -> TokenStream {
63    let args = parse_macro_input!(input as DeriveInput);
64    match r#enum::generate(args) {
65        Ok(stream) => stream.into(),
66        Err(err) => err.write_errors().into(),
67    }
68}
69
70#[proc_macro_derive(Union, attributes(oai))]
71pub fn derive_union(input: TokenStream) -> TokenStream {
72    let args = parse_macro_input!(input as DeriveInput);
73    match union::generate(args) {
74        Ok(stream) => stream.into(),
75        Err(err) => err.write_errors().into(),
76    }
77}
78
79#[proc_macro_derive(ApiResponse, attributes(oai))]
80pub fn derive_response(input: TokenStream) -> TokenStream {
81    let args = parse_macro_input!(input as DeriveInput);
82    match response::generate(args) {
83        Ok(stream) => stream.into(),
84        Err(err) => err.write_errors().into(),
85    }
86}
87
88#[proc_macro_derive(ApiRequest, attributes(oai))]
89pub fn derive_request(input: TokenStream) -> TokenStream {
90    let args = parse_macro_input!(input as DeriveInput);
91    match request::generate(args) {
92        Ok(stream) => stream.into(),
93        Err(err) => err.write_errors().into(),
94    }
95}
96
97#[proc_macro_derive(ResponseContent, attributes(oai))]
98pub fn derive_response_content(input: TokenStream) -> TokenStream {
99    let args = parse_macro_input!(input as DeriveInput);
100    match response_content::generate(args) {
101        Ok(stream) => stream.into(),
102        Err(err) => err.write_errors().into(),
103    }
104}
105
106#[proc_macro_attribute]
107#[allow(non_snake_case)]
108pub fn OpenApi(args: TokenStream, input: TokenStream) -> TokenStream {
109    let api_args = parse_nested_meta!(api::APIArgs, args);
110    let item_impl = parse_macro_input!(input as ItemImpl);
111    match api::generate(api_args, item_impl) {
112        Ok(stream) => stream.into(),
113        Err(err) => err.write_errors().into(),
114    }
115}
116
117#[proc_macro_derive(Multipart, attributes(oai))]
118pub fn derive_multipart(input: TokenStream) -> TokenStream {
119    let args = parse_macro_input!(input as DeriveInput);
120    match multipart::generate(args) {
121        Ok(stream) => stream.into(),
122        Err(err) => err.write_errors().into(),
123    }
124}
125
126#[proc_macro_derive(Tags, attributes(oai))]
127pub fn derive_tags(input: TokenStream) -> TokenStream {
128    let args = parse_macro_input!(input as DeriveInput);
129    match tags::generate(args) {
130        Ok(stream) => stream.into(),
131        Err(err) => err.write_errors().into(),
132    }
133}
134
135#[proc_macro_derive(OAuthScopes, attributes(oai))]
136pub fn derive_oauth_scopes(input: TokenStream) -> TokenStream {
137    let args = parse_macro_input!(input as DeriveInput);
138    match oauth_scopes::generate(args) {
139        Ok(stream) => stream.into(),
140        Err(err) => err.write_errors().into(),
141    }
142}
143
144#[proc_macro_derive(SecurityScheme, attributes(oai))]
145pub fn derive_security_scheme(input: TokenStream) -> TokenStream {
146    let args = parse_macro_input!(input as DeriveInput);
147    match security_scheme::generate(args) {
148        Ok(stream) => stream.into(),
149        Err(err) => err.write_errors().into(),
150    }
151}
152
153#[proc_macro_attribute]
154#[allow(non_snake_case)]
155pub fn Webhook(args: TokenStream, input: TokenStream) -> TokenStream {
156    let webhook_args = parse_nested_meta!(webhook::WebhookArgs, args);
157    let item_trait = parse_macro_input!(input as ItemTrait);
158    match webhook::generate(webhook_args, item_trait) {
159        Ok(stream) => stream.into(),
160        Err(err) => err.write_errors().into(),
161    }
162}
163
164#[proc_macro_derive(NewType, attributes(oai))]
165pub fn derive_new_type(input: TokenStream) -> TokenStream {
166    let args = parse_macro_input!(input as DeriveInput);
167    match newtype::generate(args) {
168        Ok(stream) => stream.into(),
169        Err(err) => err.write_errors().into(),
170    }
171}