api_client_macro/lib.rs
1///
2/// easily creates an api client
3///
4/// ```rust
5/// api_client_macro::generate!(ApiClient, {
6/// user {
7/// #[get "user/{}"]
8/// get_by_id(id: &str),
9///
10/// #[delete "user/{}"]
11/// delete_by_id(id: &str),
12///
13/// #[post "user"]
14/// create(),
15///
16/// #[get "users"]
17/// list()
18/// },
19/// contact {
20/// #[get "contact/{}"]
21/// get_by_id(id: &str),
22///
23/// #[delete "contact/{}"]
24/// delete_by_id(id: &str),
25///
26/// #[post "contact"]
27/// create(),
28///
29/// #[get "contact"]
30/// list()
31/// }
32/// });
33///
34/// fn main() {}
35///
36/// async fn main_async() {
37/// let client = asynchronous::Builder::new("base_url", None);
38/// client.contact_create().body("<body>").send().await.unwrap();
39/// client.contact_get_by_id("<id>").send().await.unwrap();
40/// client.user_list().query(&[("email", "<email>")]).send().await.unwrap();
41/// }
42///
43/// fn main_blocking() {
44/// let client = blocking::Builder::new("base_url", None);
45/// client.contact_create().body("<body>").send().unwrap();
46/// client.contact_get_by_id("<id>").send().unwrap();
47/// client.user_list().query(&[("email", "<email>")]).send().unwrap();
48/// }
49/// ```
50///
51#[macro_export]
52macro_rules! generate {
53 ($client_type:ident, {
54 $(
55 $resource:ident {
56 $(
57 #[$method:ident $url:literal]
58 $function:ident($($param:ident : $type:ty),*)
59 ),* $(,)?
60 }
61 ),* $(,)?
62 }) => {
63 paste::paste! {
64 mod internal {
65 pub struct [<$client_type Builder>]<T> {
66 pub(crate) base_url: String,
67 pub(crate) client: T,
68 }
69
70 impl<T> [<$client_type Builder>]<T> where T: Default {
71 pub fn new(base_url: &str, client: Option<T>) -> Self {
72 Self {
73 base_url: base_url.to_string(),
74 client: client.unwrap_or_default(),
75 }
76 }
77 }
78 }
79
80 pub mod blocking {
81 use super::internal::*;
82
83 pub type Client = reqwest::blocking::Client;
84 pub type Builder = [<$client_type Builder>]<Client>;
85
86 pub fn new(base_url: &str, client: Option<Client>) -> Builder {
87 Builder::new(base_url, client)
88 }
89
90 impl Builder {
91 $(
92 $(
93 #[allow(dead_code)]
94 pub fn [<$resource _ $function>](&self $(,$param: $type)*) -> reqwest::blocking::RequestBuilder {
95 let url = format!(concat!("{}/", $url), self.base_url $(, $param )*);
96 println!("{} {}", stringify!([<$method:upper>]), &url);
97 self.client.$method(&url)
98 }
99 )*
100 )*
101 }
102 }
103
104 pub mod asynchronous {
105 use super::internal::*;
106
107 pub type Client = reqwest::Client;
108 pub type Builder = [<$client_type Builder>]<Client>;
109
110 pub fn new(base_url: &str, client: Option<Client>) -> Builder {
111 Builder::new(base_url, client)
112 }
113
114 impl Builder {
115 $(
116 $(
117 #[allow(dead_code)]
118 pub fn [<$resource _ $function>](&self $(,$param: $type)*) -> reqwest::RequestBuilder {
119 let url = format!(concat!("{}/", $url), self.base_url $(, $param )*);
120 println!("{} {}", stringify!([<$method:upper>]), &url);
121 self.client.$method(&url)
122 }
123 )*
124 )*
125 }
126 }
127 }
128 };
129}