gcloud_sdk/rest_apis/
rest_api_client.rs1use crate::{GoogleAuthTokenGenerator, TokenSourceType, GCP_DEFAULT_SCOPES};
2use async_trait::async_trait;
3use hyper::Uri;
4use reqwest::{IntoUrl, Method, Request, RequestBuilder};
5use std::sync::Arc;
6
7#[derive(Clone)]
8pub struct GoogleRestApi {
9 pub client: reqwest::Client,
10 pub token_generator: Arc<GoogleAuthTokenGenerator>,
11}
12
13impl GoogleRestApi {
14 pub async fn new() -> crate::error::Result<Self> {
15 Self::with_token_source(TokenSourceType::Default, GCP_DEFAULT_SCOPES.clone()).await
16 }
17
18 pub async fn with_token_source(
19 token_source_type: TokenSourceType,
20 token_scopes: Vec<String>,
21 ) -> crate::error::Result<Self> {
22 let client = reqwest::Client::new();
23 Self::with_client_token_source(client, token_source_type, token_scopes).await
24 }
25
26 pub async fn with_client_token_source(
27 client: reqwest::Client,
28 token_source_type: TokenSourceType,
29 token_scopes: Vec<String>,
30 ) -> crate::error::Result<Self> {
31 let token_generator =
32 GoogleAuthTokenGenerator::new(token_source_type, token_scopes).await?;
33
34 Ok(Self {
35 client,
36 token_generator: Arc::new(token_generator),
37 })
38 }
39
40 pub async fn with_google_token<'a>(
41 &self,
42 request: RequestBuilder,
43 ) -> crate::error::Result<RequestBuilder> {
44 let token = self.token_generator.create_token().await?;
45 Ok(request.header(reqwest::header::AUTHORIZATION, token.header_value()))
46 }
47
48 pub async fn get<U: IntoUrl>(&self, url: U) -> crate::error::Result<RequestBuilder> {
49 self.with_google_token(self.client.request(Method::GET, url))
50 .await
51 }
52 pub async fn post<U: IntoUrl>(&self, url: U) -> crate::error::Result<RequestBuilder> {
53 self.with_google_token(self.client.request(Method::POST, url))
54 .await
55 }
56 pub async fn put<U: IntoUrl>(&self, url: U) -> crate::error::Result<RequestBuilder> {
57 self.with_google_token(self.client.request(Method::PUT, url))
58 .await
59 }
60 pub async fn patch<U: IntoUrl>(&self, url: U) -> crate::error::Result<RequestBuilder> {
61 self.with_google_token(self.client.request(Method::PATCH, url))
62 .await
63 }
64 pub async fn delete<U: IntoUrl>(&self, url: U) -> crate::error::Result<RequestBuilder> {
65 self.with_google_token(self.client.request(Method::DELETE, url))
66 .await
67 }
68 pub async fn head<U: IntoUrl>(&self, url: U) -> crate::error::Result<RequestBuilder> {
69 self.with_google_token(self.client.request(Method::HEAD, url))
70 .await
71 }
72}
73
74pub fn create_hyper_uri_with_params<'p, PT, TS>(url_str: &str, params: &'p PT) -> Uri
75where
76 PT: std::iter::IntoIterator<Item = (&'p str, Option<&'p TS>)> + Clone,
77 TS: std::string::ToString + 'p,
78{
79 let url_query_params: Vec<(String, String)> = params
80 .clone()
81 .into_iter()
82 .filter_map(|(k, vo)| vo.map(|v| (k.to_string(), v.to_string())))
83 .collect();
84
85 let url: url::Url = url::Url::parse_with_params(url_str, url_query_params)
86 .unwrap()
87 .as_str()
88 .parse()
89 .unwrap();
90
91 url.as_str().parse().unwrap()
92}