Skip to main content

opendal_service_gcs_grpc/
config.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::fmt::Debug;
19
20use serde::{Deserialize, Serialize};
21
22use super::backend::GcsGrpcBuilder;
23
24/// Configuration for the Google Cloud Storage gRPC service.
25#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
26#[serde(default)]
27#[non_exhaustive]
28pub struct GcsGrpcConfig {
29    /// Root path for all operations.
30    pub root: Option<String>,
31    /// Bucket name.
32    #[serde(
33        alias = "google_bucket",
34        alias = "google_bucket_name",
35        alias = "bucket_name"
36    )]
37    pub bucket: String,
38    /// gRPC endpoint.
39    pub endpoint: Option<String>,
40    /// OAuth 2.0 scope.
41    pub scope: Option<String>,
42    /// Service account used by the GCE metadata server.
43    #[serde(
44        alias = "google_service_account",
45        alias = "google_service_account_path",
46        alias = "service_account_path"
47    )]
48    pub service_account: Option<String>,
49    /// Base64-encoded service account credential.
50    #[serde(alias = "google_service_account_key", alias = "service_account_key")]
51    pub credential: Option<String>,
52    /// Path to a service account credential file.
53    #[serde(alias = "google_application_credentials")]
54    pub credential_path: Option<String>,
55    /// Send requests without authentication.
56    #[serde(alias = "google_skip_signature")]
57    pub skip_signature: bool,
58    /// Disable the GCE metadata credential provider.
59    pub disable_vm_metadata: bool,
60    /// Disable environment and well-known credential loading.
61    pub disable_config_load: bool,
62    /// OAuth 2.0 access token.
63    pub token: Option<String>,
64}
65
66impl Debug for GcsGrpcConfig {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        f.debug_struct("GcsGrpcConfig")
69            .field("root", &self.root)
70            .field("bucket", &self.bucket)
71            .field("endpoint", &self.endpoint)
72            .field("scope", &self.scope)
73            .finish_non_exhaustive()
74    }
75}
76
77impl opendal_core::Configurator for GcsGrpcConfig {
78    type Builder = GcsGrpcBuilder;
79
80    fn from_uri(uri: &opendal_core::OperatorUri) -> opendal_core::Result<Self> {
81        let mut map = uri.options().clone();
82        if let Some(name) = uri.name() {
83            map.insert("bucket".to_string(), name.to_string());
84        }
85        if let Some(root) = uri.root() {
86            map.insert("root".to_string(), root.to_string());
87        }
88        Self::from_iter(map)
89    }
90
91    fn into_builder(self) -> Self::Builder {
92        GcsGrpcBuilder {
93            config: self,
94            credential_provider_chain: None,
95        }
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use opendal_core::{Configurator, OperatorUri};
102
103    use super::*;
104
105    #[test]
106    fn from_uri_extracts_bucket_and_root() {
107        let uri = OperatorUri::new(
108            "gcs-grpc://example-bucket/path/to/root",
109            Vec::<(String, String)>::new(),
110        )
111        .unwrap();
112        let cfg = GcsGrpcConfig::from_uri(&uri).unwrap();
113        assert_eq!(cfg.bucket, "example-bucket");
114        assert_eq!(cfg.root.as_deref(), Some("path/to/root"));
115    }
116}