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
//pub use crate::generate_reqwest_client;

#[macro_export]
///
/// easily creates an api client
///
/// ```rust
/// api_client_macro::generate!(ApiClient, {
///     user {
///         get_by_id: get "user/{id}" id: &str,
///         delete_by_id: delete "user/{id}" id: &str,
///         create: post "user",
///         list: get "users"
///     },
///     contact {
///         get_by_id: get "contact/{id}" id: &str,
///         delete_by_id: delete "contact/{id}" id: &str,
///         create: post "contact",
///         list: get "contact"
///     }
/// });
/// ```
///
macro_rules! generate {
    ($client_type:ident, {
        $(
            $resource:ident {
                $(
                    $name:ident: $method:ident $url:literal $($param:ident : $type:ty)*
                ),+
             }
        ),+
    }) => {
        /* pub struct ApiClientHelper {
            base_url: String,
            client: reqwest::blocking::Client,
        } */

        paste::paste! {

            /* pub mod [<$client_type:snake>] {
                $(
                    pub mod [<$resource:snake>] {
                        $(
                            pub fn [<$name:snake>](helper: &super::super::ApiClientHelper $(, $param: $type)*) -> reqwest::blocking::RequestBuilder {
                                let url = format!(concat!("{}/", $url), helper.base_url $(, $param = $param)*);
                                helper.client.$method(&url)
                            }
                        )+
                    }
                ),+
            } */

            pub struct [<$client_type Builder>] {
                base_url: String,
                client: reqwest::blocking::Client,
            }

            impl [<$client_type Builder>] {
                pub fn new(base_url: &str, client: Option<reqwest::blocking::Client>) -> Self {
                    Self {
                        base_url: base_url.to_string(),
                        client: client.unwrap_or(reqwest::blocking::Client::new()),
                    }
                }

                $(
                    $(
                        pub fn [<$resource _ $name>](&self $(, $param: $type)*) -> reqwest::blocking::RequestBuilder {
                            let url = format!(concat!("{}/", $url), self.base_url $(, $param = $param)*);
                            println!("{} {}", stringify!([<$method:upper>]), &url);
                            self.client.$method(&url)
                        }
                    )+
                )+
            }
        }
    };
}