macro_rules! rest_method {
(
#[$method:ident $url:literal]
$function:tt($($param:ident : $type:ty),*)
) => {
#[allow(dead_code)]
pub $function(&self $(,$param: &str)*) -> reqwest::RequestBuilder {
let url = format!(concat!("{}/", $($url),*), self.base_url $(, $param)*);
println!("{} {}", stringify!([<$method:upper>]), &url);
self.client.$method(&url)
}
};
}
macro_rules! generate {
($client_type:ident, {
$(
$resource:ident {
$(
#[$method:ident $url:literal]
$function:ident($($param:ident : $type:ty),*)
),* $(,)?
}
),* $(,)?
}) => {
paste::paste! {
mod internal {
pub struct [<$client_type Builder>]<T> {
pub(crate) base_url: String,
pub(crate) client: T,
}
impl<T> [<$client_type Builder>]<T> where T: Default {
pub fn new(base_url: &str, client: Option<T>) -> Self {
Self {
base_url: base_url.to_string(),
client: client.unwrap_or_default(),
}
}
}
}
pub mod blocking {
use super::internal::*;
pub type Client = reqwest::blocking::Client;
pub type Builder = [<$client_type Builder>]<Client>;
pub fn new(base_url: &str, client: Option<Client>) -> Builder {
Builder::new(base_url, client)
}
impl Builder {
$(
$(
#[allow(dead_code)]
pub fn [<$resource _ $function>](&self $(,$param: $type)*) -> reqwest::blocking::RequestBuilder {
let url = format!(concat!("{}/", $url), self.base_url $(, $param )*);
println!("{} {}", stringify!([<$method:upper>]), &url);
self.client.$method(&url)
}
)*
)*
}
}
pub mod asynchronous {
use super::internal::*;
pub type Client = reqwest::Client;
pub type Builder = [<$client_type Builder>]<Client>;
pub fn new(base_url: &str, client: Option<Client>) -> Builder {
Builder::new(base_url, client)
}
impl Builder {
$(
$(
#[allow(dead_code)]
pub async fn [<$resource _ $function>](&self $(,$param: $type)*) -> reqwest::RequestBuilder {
let url = format!(concat!("{}/", $url), self.base_url $(, $param )*);
println!("{} {}", stringify!([<$method:upper>]), &url);
self.client.$method(&url)
}
)*
)*
}
}
}
};
}
generate!(BigQuery, {
jobs {
#[post "queries"]
query(),
#[get "jobs/{}"]
get(id: &str),
},
tables {
#[get "datasets/{}/tables"]
list(dataset_id: &str),
},
tabledata {
#[post "datasets/{}/tables/{}/insertAll"]
insert_all(dataset_id: &str, table_id: &str),
}
});
fn main() {
let blocking_client = blocking::new("base_url", None);
blocking_client.jobs_query();
blocking_client.jobs_get("job_id");
blocking_client.tables_list("dataset_id");
}