cloud_storage/
client.rs

1//! Clients for Google Cloud Storage endpoints.
2
3use std::{fmt, sync};
4
5use crate::token::TokenCache;
6
7mod bucket;
8mod bucket_access_control;
9mod default_object_access_control;
10mod hmac_key;
11mod object;
12mod object_access_control;
13
14pub use bucket::BucketClient;
15pub use bucket_access_control::BucketAccessControlClient;
16pub use default_object_access_control::DefaultObjectAccessControlClient;
17pub use hmac_key::HmacKeyClient;
18pub use object::ObjectClient;
19pub use object_access_control::ObjectAccessControlClient;
20
21/// The primary entrypoint to perform operations with Google Cloud Storage.
22pub struct Client {
23    client: reqwest::Client,
24    /// Static `Token` struct that caches
25    token_cache: sync::Arc<dyn crate::TokenCache + Send>,
26}
27
28impl fmt::Debug for Client {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        f.debug_struct("Client")
31            .field("client", &self.client)
32            .field("token_cache", &"<opaque>")
33            .finish()
34    }
35}
36
37impl Default for Client {
38    fn default() -> Self {
39        Self {
40            client: Default::default(),
41            token_cache: sync::Arc::new(crate::Token::default()),
42        }
43    }
44}
45
46impl Client {
47    /// Constructs a client with the default token provider, where it attemps to obtain the
48    /// credentials from the following locations:
49    ///
50    /// 1. Checks for the environment variable `SERVICE_ACCOUNT`, and if it exists, reads the file
51    /// at the path specified there as a credentials json file.
52    /// 2. It attemps to do the same with the `GOOGLE_APPLICATION_CREDENTIALS` var.
53    /// 3. It reads the `SERVICE_ACCOUNT_JSON` environment variable directly as json and uses that
54    /// 4. It attemps to do the same with the `GOOGLE_APPLICATION_CREDENTIALS_JSON` var.
55    pub fn new() -> Self {
56        Default::default()
57    }
58
59    /// Initializer with a provided refreshable token
60    pub fn with_cache(token: impl TokenCache + Send + 'static) -> Self {
61        Self {
62            client: Default::default(),
63            token_cache: sync::Arc::new(token),
64        }
65    }
66
67    /// Operations on [`Bucket`](crate::bucket::Bucket)s.
68    pub fn bucket(&self) -> BucketClient<'_> {
69        BucketClient(self)
70    }
71
72    /// Operations on [`BucketAccessControl`](crate::bucket_access_control::BucketAccessControl)s.
73    pub fn bucket_access_control(&self) -> BucketAccessControlClient<'_> {
74        BucketAccessControlClient(self)
75    }
76
77    /// Operations on [`DefaultObjectAccessControl`](crate::default_object_access_control::DefaultObjectAccessControl)s.
78    pub fn default_object_access_control(&self) -> DefaultObjectAccessControlClient<'_> {
79        DefaultObjectAccessControlClient(self)
80    }
81
82    /// Operations on [`HmacKey`](crate::hmac_key::HmacKey)s.
83    pub fn hmac_key(&self) -> HmacKeyClient<'_> {
84        HmacKeyClient(self)
85    }
86
87    /// Operations on [`Object`](crate::object::Object)s.
88    pub fn object(&self) -> ObjectClient<'_> {
89        ObjectClient(self)
90    }
91
92    /// Operations on [`ObjectAccessControl`](crate::object_access_control::ObjectAccessControl)s.
93    pub fn object_access_control(&self) -> ObjectAccessControlClient<'_> {
94        ObjectAccessControlClient(self)
95    }
96
97    async fn get_headers(&self) -> crate::Result<reqwest::header::HeaderMap> {
98        let mut result = reqwest::header::HeaderMap::new();
99        let token = self.token_cache.get(&self.client).await?;
100        result.insert(
101            reqwest::header::AUTHORIZATION,
102            format!("Bearer {}", token).parse().unwrap(),
103        );
104        Ok(result)
105    }
106}