clientix_codegen/
lib.rs

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