1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! # Conreg Feign
//!
//! This crate provides procedural macros for creating Feign-like declarative HTTP clients.
//!
//! # Feign Client Macro
//!
//! Used to create declarative HTTP clients similar to Java Feign. By annotating a trait with this macro,
//! implementation code for HTTP requests is automatically generated, enabling RESTful communication between microservices.
//!
//! ## Parameters
//!
//! - `service_id`: **Required**, the unique identifier of the service, used for service discovery and load balancing.
//! - `base_path`: *Optional*, the base path prefix that will be prepended to all request paths.
//! - `url`: *Optional*, directly specifies the base URL for requests; if set, `service_id` and `base_path` will be ignored.
//!
//! Example:
//! ```rust
//! #[feign_client(service_id = "user-service", base_path = "/api")]
//! trait UserService{
//! #[get("/api/users/{id}")]
//! async fn get_user(&self, id: i32) -> Result<String, FeignError>;
//!
//! // ... other methods
//! }
//!
//! // Then, you can use the generated client like this:
//! let client = UserServiceImpl::default();
//! let user = client.get_user(1).await?;
//! ```
//!
//! # Http Method Macros
//!
//! ## Supported HTTP Method Annotations
//!
//! - `#[get]`
//! - `#[post]`
//! - `#[put]`
//! - `#[delete]`
//! - `#[patch]`
//!
//! ## Parameter Binding Methods
//!
//! ### Path Parameters
//! Use `{param_name}` placeholders in the path. When a method parameter name matches the placeholder name, it is automatically bound.
//!
//! Example:
//! ```rust
//! #[get("/api/users/{id}")]
//! async fn ip(&self, id: i32) -> Result<String, FeignError>;
//! ```
//!
//! ### Query Parameters
//! Use `query = "{param}"` to specify query parameter templates.
//!
//! Example:
//! ```rust
//! #[get(path = "/api/users", query = "id={id}")]
//! async fn query(&self, id: i32) -> Result<String, FeignError>;
//! ````
//!
//! ### Form Parameters
//! Use `form = "{param}"` to specify form data, supporting `application/x-www-form-urlencoded` and `multipart/form-data`.
//!
//! Example:
//! ```rust
//! #[post(path = "/api/login", form = "{loginForm}")]
//! async fn login(&self, loginForm: reqwest::multipart::Form) -> Result<String, FeignError>;
//! ```
//!
//! ### Body Parameter
//! Use `body = "{param}"` to specify the raw string body.
//!
//! Example:
//! ```rust
//! #[post(path = "/api/post", body = "{data}")]
//! async fn post(&self, data: String) -> Result<String, FeignError>;
//! ```
//!
//! ### JSON Parameter
//! Use `json = "{param}"` to specify JSON data; it will be automatically serialized and `Content-Type: application/json` will be set.
//!
//! Note: need serde_json
//!
//! Example:
//! ```rust
//! #[post(path = "/api/post", json = "{data}")]
//! async fn post(&self, data: serde_json::Value) -> Result<String, FeignError> {}
//! ```
//!
//! ### Header Parameter
//! Use `headers("Key=Value", ...)` or `headers("Key={param}", ...)` to specify request headers, supporting both static values and dynamic parameters.
//!
//! Example:
//! ```rust
//! #[get(path = "/api/users", headers("Authorization: Bearer {token}", "Accept: application/json"))]
//! async fn get_users(&self, token: String) -> Result<String, FeignError>
//! ```
use TokenStream;
/// GET request annotation
/// POST request annotation
/// PUT request annotation
/// DELETE request annotation
/// PATCH request annotation