1#![deny(missing_docs)]
2#![deny(rustdoc::broken_intra_doc_links)]
3
4#[cfg(feature = "config")]
7mod config;
8mod controller;
9mod gateway;
10mod injectable;
11mod microservice;
12
13#[cfg(all(feature = "actix", feature = "axum"))]
14compile_error!("caelix-macros backend features `actix` and `axum` are mutually exclusive");
15
16use proc_macro::TokenStream;
17use quote::quote;
18#[cfg(any(feature = "axum", feature = "tokio"))]
19use syn::{ItemFn, parse_macro_input, parse_quote};
20
21#[cfg(feature = "config")]
23#[proc_macro_derive(Config, attributes(config))]
24pub fn config(input: TokenStream) -> TokenStream {
25 config::expand(input)
26}
27
28#[proc_macro_attribute]
35pub fn injectable(args: TokenStream, input: TokenStream) -> TokenStream {
36 injectable::expand(args, input)
37}
38
39#[proc_macro_attribute]
41pub fn microservice(args: TokenStream, input: TokenStream) -> TokenStream {
42 microservice::expand(args, input)
43}
44
45#[proc_macro_attribute]
47pub fn message_pattern(_args: TokenStream, input: TokenStream) -> TokenStream {
48 input
49}
50
51#[proc_macro_attribute]
53pub fn event_pattern(_args: TokenStream, input: TokenStream) -> TokenStream {
54 input
55}
56
57#[proc_macro_attribute]
59pub fn payload(_args: TokenStream, input: TokenStream) -> TokenStream {
60 input
61}
62
63#[proc_macro_attribute]
65pub fn context(_args: TokenStream, input: TokenStream) -> TokenStream {
66 input
67}
68
69#[proc_macro_attribute]
75pub fn guard(args: TokenStream, input: TokenStream) -> TokenStream {
76 injectable::expand(args, input)
77}
78
79#[proc_macro_attribute]
87pub fn controller(args: TokenStream, input: TokenStream) -> TokenStream {
88 controller::expand(args, input)
89}
90
91#[proc_macro_attribute]
93pub fn throttle(args: TokenStream, input: TokenStream) -> TokenStream {
94 controller::expand_controller_throttle_marker(args, input, false)
95}
96
97#[proc_macro_attribute]
99pub fn skip_throttle(args: TokenStream, input: TokenStream) -> TokenStream {
100 controller::expand_controller_throttle_marker(args, input, true)
101}
102
103#[proc_macro_attribute]
108pub fn response(_args: TokenStream, input: TokenStream) -> TokenStream {
109 input
110}
111
112#[proc_macro_attribute]
117pub fn errors(_args: TokenStream, input: TokenStream) -> TokenStream {
118 input
119}
120
121#[proc_macro_attribute]
126pub fn request_header(_args: TokenStream, input: TokenStream) -> TokenStream {
127 input
128}
129
130#[proc_macro_attribute]
135pub fn security(_args: TokenStream, input: TokenStream) -> TokenStream {
136 input
137}
138
139#[proc_macro_attribute]
147pub fn gateway(args: TokenStream, input: TokenStream) -> TokenStream {
148 gateway::expand(args, input)
149}
150
151#[proc_macro_attribute]
158pub fn on_message(_args: TokenStream, input: TokenStream) -> TokenStream {
159 input
160}
161
162#[proc_macro_attribute]
167pub fn main(_args: TokenStream, item: TokenStream) -> TokenStream {
168 #[cfg(any(feature = "axum", feature = "tokio"))]
169 {
170 expand_tokio_runtime(item, false)
171 }
172 #[cfg(not(any(feature = "axum", feature = "tokio")))]
173 {
174 let item = proc_macro2::TokenStream::from(item);
175 quote! { #[caelix::__actix_web::rt::main(system = "caelix::__actix_web::rt::System")] #item }.into()
176 }
177}
178
179#[proc_macro_attribute]
184pub fn test(_args: TokenStream, item: TokenStream) -> TokenStream {
185 #[cfg(any(feature = "axum", feature = "tokio"))]
186 {
187 expand_tokio_runtime(item, true)
188 }
189 #[cfg(not(any(feature = "axum", feature = "tokio")))]
190 {
191 let item = proc_macro2::TokenStream::from(item);
192 quote! { #[caelix::__actix_web::rt::test(system = "caelix::__actix_web::rt::System")] #item }.into()
193 }
194}
195
196#[cfg(any(feature = "axum", feature = "tokio"))]
197fn expand_tokio_runtime(item: TokenStream, is_test: bool) -> TokenStream {
198 let mut function = parse_macro_input!(item as ItemFn);
199 let body = function.block;
200 function.sig.asyncness = None;
201 function.block = Box::new(parse_quote!({
202 caelix::__tokio::runtime::Builder::new_multi_thread()
203 .enable_all()
204 .build()
205 .expect("failed to build the Caelix runtime")
206 .block_on(async #body)
207 }));
208 if is_test {
209 function
210 .attrs
211 .push(parse_quote!(#[::core::prelude::v1::test]));
212 }
213 quote!(#function).into()
214}