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
48- consumes - content-type for request
49- produces - content-type for response
50
51GET method supports argument macros:
52- #[segment] - maps method arguments to path segments
53- #[query] - maps method arguments to query parameters
54- #[header] - maps method arguments to request headers
55- #[body] - maps method arguments to request body
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    parse_method(Method::GET, item, attrs)
66}
67
68/**
69A procedural macro for building an HTTP POST method of trait. It includes the following attributes:
70- path - a part of the URL path
71- consumes - content-type for request
72- produces - content-type for response
73
74POST method supports argument macros:
75- #[segment] - maps method arguments to path segments
76- #[query] - maps method arguments to query parameters
77- #[header] - maps method arguments to request headers
78- #[body] - maps method arguments to request body
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
96- consumes - content-type for request
97- produces - content-type for response
98
99PUT method supports argument macros:
100- #[segment] - maps method arguments to path segments
101- #[query] - maps method arguments to query parameters
102- #[header] - maps method arguments to request headers
103- #[body] - maps method arguments to request body
104
105Example:
106```
107#[put(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
108fn put(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str, #[body] request: RequestBody) -> ClientixResult<ClientixResponse<String>>;
109```
110
111RequestBody must implement the #[data_transfer] macro.
112*/
113#[proc_macro_attribute]
114pub fn put(attrs: TokenStream, item: TokenStream) -> TokenStream {
115    parse_method(Method::PUT, item, attrs)
116}
117
118/**
119A procedural macro for building an HTTP DELETE method of trait. It includes the following attributes:
120- path - a part of the URL path
121- consumes - content-type for request
122- produces - content-type for response
123
124DELETE method supports argument macros:
125- #[segment] - maps method arguments to path segments
126- #[query] - maps method arguments to query parameters
127- #[header] - maps method arguments to request headers
128- #[body] - maps method arguments to request body
129
130Example:
131```
132#[delete(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
133fn delete(&self, #[segment] path_query: &str, #[query] query_param: &str, #[header] authorization: &str) -> ClientixResult<ClientixResponse<String>>;
134```
135*/
136#[proc_macro_attribute]
137pub fn delete(attrs: TokenStream, item: TokenStream) -> TokenStream {
138    parse_method(Method::DELETE, item, attrs)
139}
140
141/**
142A procedural macro for building an HTTP HEAD method of trait. It includes the following attributes:
143- path - a part of the URL path
144- consumes - content-type for request
145- produces - content-type for response
146
147HEAD method supports argument macros:
148- #[segment] - maps method arguments to path segments
149- #[query] - maps method arguments to query parameters
150- #[header] - maps method arguments to request headers
151- #[body] - maps method arguments to request body
152
153Example:
154```
155#[head(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
156fn head(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
157```
158*/
159#[proc_macro_attribute]
160pub fn head(attrs: TokenStream, item: TokenStream) -> TokenStream {
161    parse_method(Method::HEAD, item, attrs)
162}
163
164/**
165A procedural macro for building an HTTP PATCH method of trait. It includes the following attributes:
166- path - a part of the URL path
167- consumes - content-type for request
168- produces - content-type for response
169
170PATCH method supports argument macros:
171- #[segment] - maps method arguments to path segments
172- #[query] - maps method arguments to query parameters
173- #[header] - maps method arguments to request headers
174- #[body] - maps method arguments to request body
175
176Example:
177```
178#[patch(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
179fn patch(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
180```
181*/
182#[proc_macro_attribute]
183pub fn patch(attrs: TokenStream, item: TokenStream) -> TokenStream {
184    parse_method(Method::PATCH, item, attrs)
185}
186
187#[proc_macro_attribute]
188pub fn header(attrs: TokenStream, item: TokenStream) -> TokenStream {
189    parse_header(item, attrs)
190}
191
192/**
193A procedural macro for generating DTO objects.
194
195Example:
196```
197#[data_transfer]
198pub struct CreateObjectRequest {
199    pub name: String,
200    pub data: HashMap<String, String>,
201}
202
203#[data_transfer]
204pub struct CreatedObjectResponse {
205    pub id: String,
206    pub name: String,
207    pub data: HashMap<String, String>
208}
209```
210*/
211#[proc_macro_attribute]
212pub fn data_transfer(_: TokenStream, item: TokenStream) -> TokenStream {
213    let item = parse_macro_input!(item as ItemStruct);
214
215    // TODO: научить data_transfer использовать все возможности serde на максимум
216    TokenStream::from(quote! {
217        #[derive(clientix::prelude::serde::Serialize, clientix::prelude::serde::Deserialize, Debug, Clone)]
218        #[serde(crate = "clientix::prelude::serde")]
219        #item
220    })
221}
222
223// TODO: implemented HTTP-methods based independent functions
224// TODO: implemented building client based struct params