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 PATCH 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
167PATCH 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#[patch(path = "/{path_query}", consumes = "application/json", produces = "application/json")]
176fn patch(&self, #[segment] path_query: &str, #[query] query_param: &str) -> ClientixResult<ClientixResponse<String>>;
177```
178*/
179#[proc_macro_attribute]
180pub fn patch(attrs: TokenStream, item: TokenStream) -> TokenStream {
181    parse_method(Method::PATCH, item, attrs)
182}
183
184/**
185// TODO: not supported
186*/
187#[proc_macro_attribute]
188pub fn header(attrs: TokenStream, item: TokenStream) -> TokenStream {
189    TokenStream::default() // TODO:
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    TokenStream::from(quote! {
216        #[derive(clientix::prelude::serde::Serialize, clientix::prelude::serde::Deserialize, Debug, Clone)]
217        #[serde(crate = "clientix::prelude::serde")]
218        #item
219    })
220}
221
222// TODO: implemented HTTP-methods based independent functions
223// TODO: implemented building client based struct params