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}