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 parse_client(item, attrs)
41}
42
43/**
44A procedural macro for building an HTTP GET method of trait. It includes the following attributes:
45- path - a part of the URL path (String)
46- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
47- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
48
49GET method supports argument macros:
50- #[segment] - maps method arguments to path segments (simple types, String)
51- #[query] - maps method arguments to query parameters (simple types, String)
52- #[header] - maps method arguments to request headers (simple types, String)
53- #[body] - maps method arguments to request body (object implemented #[data_transfer])
54- #[placeholder] - maps method arguments to request header placeholders
55
56Example:
57```
58#[get(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
59fn get(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str) -> ClientixResult<ClientixResponse<String>>;
60```
61*/
62#[proc_macro_attribute]
63pub fn get(attrs: TokenStream, item: TokenStream) -> TokenStream {
64 parse_method(Method::GET, item, attrs)
65}
66
67/**
68A procedural macro for building an HTTP POST method of trait. It includes the following attributes:
69- path - a part of the URL path (String)
70- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
71- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
72
73POST method supports argument macros:
74- #[segment] - maps method arguments to path segments (simple types, String)
75- #[query] - maps method arguments to query parameters (simple types, String)
76- #[header] - maps method arguments to request headers (simple types, String)
77- #[body] - maps method arguments to request body (object implemented #[data_transfer])
78- #[placeholder] - maps method arguments to request header placeholders
79
80Example:
81```
82#[post(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
83fn post(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str, #[body] request: RequestBody) -> ClientixResult<ClientixResponse<String>>;
84```
85
86RequestBody must implement the #[data_transfer] macro.
87*/
88#[proc_macro_attribute]
89pub fn post(attrs: TokenStream, item: TokenStream) -> TokenStream {
90 parse_method(Method::POST, item, attrs)
91}
92
93/**
94A procedural macro for building an HTTP PUT method of trait. It includes the following attributes:
95- path - a part of the URL path (String)
96- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
97- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
98
99PUT method supports argument macros:
100- #[segment] - maps method arguments to path segments (simple types, String)
101- #[query] - maps method arguments to query parameters (simple types, String)
102- #[header] - maps method arguments to request headers (simple types, String)
103- #[body] - maps method arguments to request body (object implemented #[data_transfer])
104- #[placeholder] - maps method arguments to request header placeholders
105
106Example:
107```
108#[put(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
109fn put(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str, #[body] request: RequestBody) -> ClientixResult<ClientixResponse<String>>;
110```
111
112RequestBody must implement the #[data_transfer] macro.
113*/
114#[proc_macro_attribute]
115pub fn put(attrs: TokenStream, item: TokenStream) -> TokenStream {
116 parse_method(Method::PUT, item, attrs)
117}
118
119/**
120A procedural macro for building an HTTP DELETE method of trait. It includes the following attributes:
121- path - a part of the URL path (String)
122- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
123- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
124
125DELETE method supports argument macros:
126- #[segment] - maps method arguments to path segments (simple types, String)
127- #[query] - maps method arguments to query parameters (simple types, String)
128- #[header] - maps method arguments to request headers (simple types, String)
129- #[body] - maps method arguments to request body (object implemented #[data_transfer])
130- #[placeholder] - maps method arguments to request header placeholders
131
132Example:
133```
134#[delete(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
135fn delete(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str) -> ClientixResult<ClientixResponse<String>>;
136```
137*/
138#[proc_macro_attribute]
139pub fn delete(attrs: TokenStream, item: TokenStream) -> TokenStream {
140 parse_method(Method::DELETE, item, attrs)
141}
142
143/**
144A procedural macro for building an HTTP HEAD method of trait. It includes the following attributes:
145- path - a part of the URL path (String)
146- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
147- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
148
149HEAD method supports argument macros:
150- #[segment] - maps method arguments to path segments (simple types, String)
151- #[query] - maps method arguments to query parameters (simple types, String)
152- #[header] - maps method arguments to request headers (simple types, String)
153- #[body] - maps method arguments to request body (object implemented #[data_transfer])
154- #[placeholder] - maps method arguments to request header placeholders
155
156Example:
157```
158#[head(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
159fn head(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
160```
161*/
162#[proc_macro_attribute]
163pub fn head(attrs: TokenStream, item: TokenStream) -> TokenStream {
164 parse_method(Method::HEAD, item, attrs)
165}
166
167/**
168A procedural macro for building an HTTP PATCH method of trait. It includes the following attributes:
169- path - a part of the URL path (String)
170- consumes - content type for request, support: application/json, application/xml, application/x-www-form-urlencoded (String)
171- produces - accept type for response, support: application/json, application/xml, application/x-www-form-urlencoded (String)
172
173PATCH method supports argument macros:
174- #[segment] - maps method arguments to path segments (simple types, String)
175- #[query] - maps method arguments to query parameters (simple types, String)
176- #[header] - maps method arguments to request headers (simple types, String)
177- #[body] - maps method arguments to request body (object implemented #[data_transfer])
178- #[placeholder] - maps method arguments to request header placeholders
179
180Example:
181```
182#[patch(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
183fn patch(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
184```
185*/
186#[proc_macro_attribute]
187pub fn patch(attrs: TokenStream, item: TokenStream) -> TokenStream {
188 parse_method(Method::PATCH, item, attrs)
189}
190
191/**
192A procedural macro for adding HTTP headers to a request. It includes the following attributes:
193- name - HTTP header name (String)
194- value - HTTP header value (String)
195- sensitive - sensitive HTTP header value (true/false)
196
197It also supports filling #[placeholder] into header values.
198
199Examples:
200```
201#[header(name = "Content-Type", value = "application/json")]
202#[header(name = "Authorization", value = "Bearer {token}", sensitive = true)]
203#[get(path = "/", consumes = "application/json", produces = "application/json")]
204fn get(&self, #[placeholder] token: &str) -> ClientixResult<ClientixResponse<String>>;
205```
206*/
207#[proc_macro_attribute]
208pub fn header(attrs: TokenStream, item: TokenStream) -> TokenStream {
209 parse_header(item, attrs)
210}
211
212/**
213A procedural macro for generating DTO objects.
214
215Example:
216```
217#[data_transfer]
218pub struct CreateObjectRequest {
219 pub name: String,
220 pub data: HashMap<String, String>,
221}
222
223#[data_transfer]
224pub struct CreatedObjectResponse {
225 pub id: String,
226 pub name: String,
227 pub data: HashMap<String, String>
228}
229```
230*/
231#[proc_macro_attribute]
232pub fn data_transfer(_: TokenStream, item: TokenStream) -> TokenStream {
233 let item = parse_macro_input!(item as ItemStruct);
234 let vis = item.vis.clone();
235 let ident = item.ident.clone();
236 let fields = item.fields.clone();
237
238 // TODO: научить data_transfer использовать все возможности serde на максимум
239 TokenStream::from(quote! {
240 #[derive(clientix::prelude::serde::Serialize, clientix::prelude::serde::Deserialize, Debug, Clone)]
241 #[serde(crate = "clientix::prelude::serde")]
242 #vis struct #ident #fields
243 })
244}
245
246// TODO: implemented HTTP-methods based independent functions
247// TODO: implemented building client based struct params