clientix_codegen/lib.rs
1mod method;
2mod client;
3mod return_kind;
4
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::{parse_macro_input, ItemStruct};
8use clientix_core::prelude::reqwest::Method;
9use crate::client::parse_client;
10use crate::method::parse_method;
11
12/**
13A procedural macro for building an HTTP client. It includes the following attributes:
14- url - the base part of the client’s URL, e.g. http://localhost:8080
15- path - an additional part of the URL path that precedes method paths
16- async - if true, the client is asynchronous; otherwise, it is blocking
17
18Example:
19```
20#[clientix(url = "http://localhost:8080")]
21trait ExampleClient {
22
23 #[get(path = "/", consumes = "application/json", produces = "application/json")]
24 fn get(&self) -> ClientixResult<ClientixResponse<String>>;
25
26}
27```
28
29The client also supports configuring parameters imperatively. Example:
30```
31let client = ExampleClient::config()
32 .url("http://localhost:8080")
33 .path("/test")
34 .setup();
35```
36*/
37#[proc_macro_attribute]
38pub fn clientix(attrs: TokenStream, item: TokenStream) -> TokenStream {
39 parse_client(item, attrs)
40}
41
42/**
43A procedural macro for building an HTTP GET method of trait. It includes the following attributes:
44- path - a part of the URL path
45- consumes - content-type for request
46- produces - content-type for response
47
48GET method supports argument macros:
49- #[segment] - maps method arguments to path segments
50- #[query] - maps method arguments to query parameters
51- #[header] - maps method arguments to request headers
52- #[body] - maps method arguments to request body
53
54Example:
55```
56#[get(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
57fn get(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str) -> ClientixResult<ClientixResponse<String>>;
58```
59*/
60#[proc_macro_attribute]
61pub fn get(attrs: TokenStream, item: TokenStream) -> TokenStream {
62 parse_method(Method::GET, item, attrs)
63}
64
65/**
66A procedural macro for building an HTTP POST method of trait. It includes the following attributes:
67- path - a part of the URL path
68- consumes - content-type for request
69- produces - content-type for response
70
71POST method supports argument macros:
72- #[segment] - maps method arguments to path segments
73- #[query] - maps method arguments to query parameters
74- #[header] - maps method arguments to request headers
75- #[body] - maps method arguments to request body
76
77Example:
78```
79#[post(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
80fn post(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str, #[body] request: RequestBody) -> ClientixResult<ClientixResponse<String>>;
81```
82
83RequestBody must implement the #[data_transfer] macro.
84*/
85#[proc_macro_attribute]
86pub fn post(attrs: TokenStream, item: TokenStream) -> TokenStream {
87 parse_method(Method::POST, item, attrs)
88}
89
90/**
91A procedural macro for building an HTTP PUT method of trait. It includes the following attributes:
92- path - a part of the URL path
93- consumes - content-type for request
94- produces - content-type for response
95
96PUT method supports argument macros:
97- #[segment] - maps method arguments to path segments
98- #[query] - maps method arguments to query parameters
99- #[header] - maps method arguments to request headers
100- #[body] - maps method arguments to request body
101
102Example:
103```
104#[put(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
105fn put(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str, #[body] request: RequestBody) -> ClientixResult<ClientixResponse<String>>;
106```
107
108RequestBody must implement the #[data_transfer] macro.
109*/
110#[proc_macro_attribute]
111pub fn put(attrs: TokenStream, item: TokenStream) -> TokenStream {
112 parse_method(Method::PUT, item, attrs)
113}
114
115/**
116A procedural macro for building an HTTP DELETE method of trait. It includes the following attributes:
117- path - a part of the URL path
118- consumes - content-type for request
119- produces - content-type for response
120
121DELETE method supports argument macros:
122- #[segment] - maps method arguments to path segments
123- #[query] - maps method arguments to query parameters
124- #[header] - maps method arguments to request headers
125- #[body] - maps method arguments to request body
126
127Example:
128```
129#[delete(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
130fn delete(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str) -> ClientixResult<ClientixResponse<String>>;
131```
132*/
133#[proc_macro_attribute]
134pub fn delete(attrs: TokenStream, item: TokenStream) -> TokenStream {
135 parse_method(Method::DELETE, item, attrs)
136}
137
138/**
139A procedural macro for building an HTTP HEAD method of trait. It includes the following attributes:
140- path - a part of the URL path
141- consumes - content-type for request
142- produces - content-type for response
143
144HEAD method supports argument macros:
145- #[segment] - maps method arguments to path segments
146- #[query] - maps method arguments to query parameters
147- #[header] - maps method arguments to request headers
148- #[body] - maps method arguments to request body
149
150Example:
151```
152#[head(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
153fn head(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
154```
155*/
156#[proc_macro_attribute]
157pub fn head(attrs: TokenStream, item: TokenStream) -> TokenStream {
158 parse_method(Method::HEAD, item, attrs)
159}
160
161/**
162A procedural macro for building an HTTP OPTIONS method of trait. It includes the following attributes:
163- path - a part of the URL path
164- consumes - content-type for request
165- produces - content-type for response
166
167OPTIONS method supports argument macros:
168- #[segment] - maps method arguments to path segments
169- #[query] - maps method arguments to query parameters
170- #[header] - maps method arguments to request headers
171- #[body] - maps method arguments to request body
172
173Example:
174```
175#[options(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
176fn options(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
177```
178*/
179#[proc_macro_attribute]
180pub fn options(attrs: TokenStream, item: TokenStream) -> TokenStream {
181 parse_method(Method::OPTIONS, item, attrs)
182}
183
184/**
185A procedural macro for building an HTTP PATCH method of trait. It includes the following attributes:
186- path - a part of the URL path
187- consumes - content-type for request
188- produces - content-type for response
189
190PATCH method supports argument macros:
191- #[segment] - maps method arguments to path segments
192- #[query] - maps method arguments to query parameters
193- #[header] - maps method arguments to request headers
194- #[body] - maps method arguments to request body
195
196Example:
197```
198#[patch(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
199fn options(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
200```
201*/
202#[proc_macro_attribute]
203pub fn patch(attrs: TokenStream, item: TokenStream) -> TokenStream {
204 parse_method(Method::PATCH, item, attrs)
205}
206
207/**
208// TODO: not supported
209*/
210#[proc_macro_attribute]
211pub fn header(attrs: TokenStream, item: TokenStream) -> TokenStream {
212 TokenStream::default() // TODO:
213}
214
215/**
216A procedural macro for generating DTO objects.
217
218Example:
219```
220#[data_transfer]
221pub struct CreateObjectRequest {
222 pub name: String,
223 pub data: HashMap<String, String>,
224}
225
226#[data_transfer]
227pub struct CreatedObjectResponse {
228 pub id: String,
229 pub name: String,
230 pub data: HashMap<String, String>
231}
232```
233*/
234#[proc_macro_attribute]
235pub fn data_transfer(_: TokenStream, item: TokenStream) -> TokenStream {
236 let item = parse_macro_input!(item as ItemStruct);
237
238 TokenStream::from(quote! {
239 #[derive(clientix::prelude::serde::Serialize, clientix::prelude::serde::Deserialize, Debug, Clone)]
240 #[serde(crate = "clientix::prelude::serde")]
241 #item
242 })
243}
244
245// TODO: implemented HTTP-methods based independent functions
246// TODO: implemented building client based struct params