clientix_codegen/lib.rs
1mod client;
2mod method;
3mod utils;
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_header;
11use crate::method::parse_method;
12
13/**
14A procedural macro for building an HTTP client. It includes the following attributes:
15- url - the base part of the client’s URL, e.g. http://localhost:8080
16- path - an additional part of the URL path that precedes method paths
17- async - if true, the client is asynchronous; otherwise, it is blocking
18
19Example:
20```
21#[clientix(url = "http://localhost:8080")]
22trait ExampleClient {
23
24 #[get(path = "/", consumes = "application/json", produces = "application/json")]
25 fn get(&self) -> ClientixResult<ClientixResponse<String>>;
26
27}
28```
29
30The client also supports configuring parameters imperatively. Example:
31```
32let client = ExampleClient::config()
33 .url("http://localhost:8080")
34 .path("/test")
35 .setup();
36```
37*/
38#[proc_macro_attribute]
39pub fn clientix(attrs: TokenStream, item: TokenStream) -> TokenStream {
40 // TODO: научить clientix работать со структурными объектам, а не только с trait
41 parse_client(item, attrs)
42}
43
44/**
45A procedural macro for building an HTTP GET method of trait. It includes the following attributes:
46- path - a part of the URL path (String)
47- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
48- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
49
50GET method supports argument macros:
51- #[segment] - maps method arguments to path segments (simple types, String)
52- #[query] - maps method arguments to query parameters (simple types, String)
53- #[header] - maps method arguments to request headers (simple types, String)
54- #[body] - maps method arguments to request body (object implemented #[data_transfer])
55- #[placeholder] - maps method arguments to request header placeholders
56
57Example:
58```
59#[get(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
60fn get(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str) -> ClientixResult<ClientixResponse<String>>;
61```
62*/
63#[proc_macro_attribute]
64pub fn get(attrs: TokenStream, item: TokenStream) -> TokenStream {
65 // TODO: научить get работать с независимыми функциями и со структурными методами (блок impl)
66 parse_method(Method::GET, item, attrs)
67}
68
69/**
70A procedural macro for building an HTTP POST method of trait. It includes the following attributes:
71- path - a part of the URL path (String)
72- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
73- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
74
75POST method supports argument macros:
76- #[segment] - maps method arguments to path segments (simple types, String)
77- #[query] - maps method arguments to query parameters (simple types, String)
78- #[header] - maps method arguments to request headers (simple types, String)
79- #[body] - maps method arguments to request body (object implemented #[data_transfer])
80- #[placeholder] - maps method arguments to request header placeholders
81
82Example:
83```
84#[post(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
85fn post(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str, #[body] request: RequestBody) -> ClientixResult<ClientixResponse<String>>;
86```
87
88RequestBody must implement the #[data_transfer] macro.
89*/
90#[proc_macro_attribute]
91pub fn post(attrs: TokenStream, item: TokenStream) -> TokenStream {
92 // TODO: научить post работать с независимыми функциями и со структурными методами (блок impl)
93 parse_method(Method::POST, item, attrs)
94}
95
96/**
97A procedural macro for building an HTTP PUT method of trait. It includes the following attributes:
98- path - a part of the URL path (String)
99- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
100- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
101
102PUT method supports argument macros:
103- #[segment] - maps method arguments to path segments (simple types, String)
104- #[query] - maps method arguments to query parameters (simple types, String)
105- #[header] - maps method arguments to request headers (simple types, String)
106- #[body] - maps method arguments to request body (object implemented #[data_transfer])
107- #[placeholder] - maps method arguments to request header placeholders
108
109Example:
110```
111#[put(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
112fn put(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str, #[body] request: RequestBody) -> ClientixResult<ClientixResponse<String>>;
113```
114
115RequestBody must implement the #[data_transfer] macro.
116*/
117#[proc_macro_attribute]
118pub fn put(attrs: TokenStream, item: TokenStream) -> TokenStream {
119 // TODO: научить put работать с независимыми функциями и со структурными методами (блок impl)
120 parse_method(Method::PUT, item, attrs)
121}
122
123/**
124A procedural macro for building an HTTP DELETE method of trait. It includes the following attributes:
125- path - a part of the URL path (String)
126- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
127- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
128
129DELETE method supports argument macros:
130- #[segment] - maps method arguments to path segments (simple types, String)
131- #[query] - maps method arguments to query parameters (simple types, String)
132- #[header] - maps method arguments to request headers (simple types, String)
133- #[body] - maps method arguments to request body (object implemented #[data_transfer])
134- #[placeholder] - maps method arguments to request header placeholders
135
136Example:
137```
138#[delete(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
139fn delete(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str) -> ClientixResult<ClientixResponse<String>>;
140```
141*/
142#[proc_macro_attribute]
143pub fn delete(attrs: TokenStream, item: TokenStream) -> TokenStream {
144 // TODO: научить delete работать с независимыми функциями и со структурными методами (блок impl)
145 parse_method(Method::DELETE, item, attrs)
146}
147
148/**
149A procedural macro for building an HTTP HEAD method of trait. It includes the following attributes:
150- path - a part of the URL path (String)
151- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
152- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
153
154HEAD method supports argument macros:
155- #[segment] - maps method arguments to path segments (simple types, String)
156- #[query] - maps method arguments to query parameters (simple types, String)
157- #[header] - maps method arguments to request headers (simple types, String)
158- #[body] - maps method arguments to request body (object implemented #[data_transfer])
159- #[placeholder] - maps method arguments to request header placeholders
160
161Example:
162```
163#[head(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
164fn head(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
165```
166*/
167#[proc_macro_attribute]
168pub fn head(attrs: TokenStream, item: TokenStream) -> TokenStream {
169 // TODO: научить head работать с независимыми функциями и со структурными методами (блок impl)
170 parse_method(Method::HEAD, item, attrs)
171}
172
173/**
174A procedural macro for building an HTTP PATCH method of trait. It includes the following attributes:
175- path - a part of the URL path (String)
176- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
177- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
178
179PATCH method supports argument macros:
180- #[segment] - maps method arguments to path segments (simple types, String)
181- #[query] - maps method arguments to query parameters (simple types, String)
182- #[header] - maps method arguments to request headers (simple types, String)
183- #[body] - maps method arguments to request body (object implemented #[data_transfer])
184- #[placeholder] - maps method arguments to request header placeholders
185
186Example:
187```
188#[patch(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
189fn patch(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
190```
191*/
192#[proc_macro_attribute]
193pub fn patch(attrs: TokenStream, item: TokenStream) -> TokenStream {
194 // TODO: научить patch работать с независимыми функциями и со структурными методами (блок impl)
195 parse_method(Method::PATCH, item, attrs)
196}
197
198/**
199A procedural macro for adding HTTP headers to a request. It includes the following attributes:
200- name - HTTP header name (String)
201- value - HTTP header value (String)
202- sensitive - sensitive HTTP header value (true/false)
203
204It also supports filling #[placeholder] into header values.
205
206Examples:
207```
208#[header(name = "Content-Type", value = "application/json")]
209#[header(name = "Authorization", value = "Bearer {token}", sensitive = true)]
210#[get(path = "/", consumes = "application/json", produces = "application/json")]
211fn get(&self, #[placeholder] token: &str) -> ClientixResult<ClientixResponse<String>>;
212```
213*/
214#[proc_macro_attribute]
215pub fn header(attrs: TokenStream, item: TokenStream) -> TokenStream {
216 parse_header(item, attrs)
217}
218
219/**
220A procedural macro for generating DTO objects.
221
222Example:
223```
224#[data_transfer]
225pub struct CreateObjectRequest {
226 pub name: String,
227 pub data: HashMap<String, String>,
228}
229
230#[data_transfer]
231pub struct CreatedObjectResponse {
232 pub id: String,
233 pub name: String,
234 pub data: HashMap<String, String>
235}
236```
237*/
238#[proc_macro_attribute]
239pub fn data_transfer(_: TokenStream, item: TokenStream) -> TokenStream {
240 let item = parse_macro_input!(item as ItemStruct);
241 let vis = item.vis.clone();
242 let ident = item.ident.clone();
243 let fields = item.fields.clone();
244
245 // TODO: научить data_transfer использовать все возможности serde на максимум, сделать так,
246 // чтобы подобный подход не вредил блоку derive и другим макросам и дал возможность пользователю самому решать о содержимом derive также
247 TokenStream::from(quote! {
248 #[derive(clientix::prelude::serde::Serialize, clientix::prelude::serde::Deserialize, Debug, Clone)]
249 #[serde(crate = "clientix::prelude::serde")]
250 #vis struct #ident #fields
251 })
252}
253
254#[proc_macro_attribute]
255pub fn request_args(_attrs: TokenStream, _item: TokenStream) -> TokenStream {
256 // TODO: реализовать соответствующую логику для парсинга структуры аргументов запроса,
257 // включая #[segment], #[placeholder], #[query], #[header], #[body]. Необходимо для поддержки
258 // аргументов запроса с макросом #[args]. Необходима имплементация геттеров для получения
259 // соответствующих значений полей
260 TokenStream::from(quote! {})
261}
262
263#[proc_macro_derive(RequestArgs, attributes(segment, placeholder, query, header, body))]
264pub fn request_args_derive(_item: TokenStream) -> TokenStream {
265 TokenStream::from(quote! {})
266}