Skip to main content

google_cloud_bigquery/write/
client_builder.rs

1// Copyright 2026 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::ClientBuilderResult as BuilderResult;
16use crate::client::Write;
17use gaxi::options::ClientConfig;
18use google_cloud_auth::credentials::Credentials;
19
20/// A builder for [Write].
21///
22/// # Example
23/// ```
24/// # use google_cloud_bigquery::client::Write;
25/// # async fn sample() -> anyhow::Result<()> {
26/// let builder = Write::builder();
27/// let client = builder
28///     .with_endpoint("https://bigquerystoragewrite.googleapis.com")
29///     .build()
30///     .await?;
31/// # Ok(()) }
32/// ```
33#[derive(Debug)]
34pub struct ClientBuilder {
35    pub(super) config: ClientConfig,
36}
37
38impl ClientBuilder {
39    pub(super) fn new() -> Self {
40        Self {
41            config: ClientConfig::default(),
42        }
43    }
44
45    /// Creates a new client.
46    ///
47    /// # Example
48    /// ```
49    /// # use google_cloud_bigquery::client::Write;
50    /// # async fn sample() -> anyhow::Result<()> {
51    /// let client = Write::builder().build().await?;
52    /// # Ok(()) }
53    /// ```
54    pub async fn build(self) -> BuilderResult<Write> {
55        Write::new(self).await
56    }
57
58    /// Sets the endpoint.
59    ///
60    /// # Example
61    /// ```
62    /// # use google_cloud_bigquery::client::Write;
63    /// # async fn sample() -> anyhow::Result<()> {
64    /// let client = Write::builder()
65    ///     .with_endpoint("https://private.googleapis.com")
66    ///     .build()
67    ///     .await?;
68    /// # Ok(()) }
69    /// ```
70    pub fn with_endpoint<V: Into<String>>(mut self, v: V) -> Self {
71        self.config.endpoint = Some(v.into());
72        self
73    }
74
75    /// Configure the universe domain.
76    ///
77    /// The universe domain is the default service domain for a given cloud universe.
78    /// The default value is "googleapis.com".
79    ///
80    /// # Example
81    /// ```
82    /// # use google_cloud_bigquery::client::Write;
83    /// # async fn sample() -> anyhow::Result<()> {
84    /// let client = Write::builder()
85    ///     .with_universe_domain("googleapis.com")
86    ///     .build()
87    ///     .await?;
88    /// # Ok(()) }
89    /// ```
90    pub fn with_universe_domain<V: Into<String>>(mut self, v: V) -> Self {
91        self.config.universe_domain = Some(v.into());
92        self
93    }
94
95    /// Configures the authentication credentials.
96    ///
97    /// More information about valid credentials types can be found in the
98    /// [google-cloud-auth] crate documentation.
99    ///
100    /// # Example
101    /// ```
102    /// # use google_cloud_bigquery::client::Write;
103    /// # async fn sample() -> anyhow::Result<()> {
104    /// use google_cloud_auth::credentials::mds;
105    /// let client = Write::builder()
106    ///     .with_credentials(
107    ///         mds::Builder::default()
108    ///             .with_scopes(["https://www.googleapis.com/auth/cloud-platform.read-only"])
109    ///             .build()?)
110    ///     .build()
111    ///     .await?;
112    /// # Ok(()) }
113    /// ```
114    ///
115    /// [google-cloud-auth]: https://docs.rs/google-cloud-auth
116    pub fn with_credentials<V: Into<Credentials>>(mut self, v: V) -> Self {
117        self.config.cred = Some(v.into());
118        self
119    }
120
121    /// Configure the number of subchannels used by the client.
122    ///
123    /// # Example
124    /// ```
125    /// # use google_cloud_bigquery::client::Write;
126    /// # async fn sample() -> anyhow::Result<()> {
127    /// let count = std::thread::available_parallelism()?.get();
128    /// let client = Write::builder()
129    ///     .with_grpc_subchannel_count(count)
130    ///     .build()
131    ///     .await?;
132    /// # Ok(()) }
133    /// ```
134    ///
135    /// gRPC-based clients may exhibit high latency if many requests need to be
136    /// demuxed over a single HTTP/2 connection (often called a *subchannel* in
137    /// gRPC).
138    ///
139    /// Consider using more subchannels if your application creates many
140    /// writers. Consider using fewer subchannels if your application needs the
141    /// file descriptors for other purposes.
142    pub fn with_grpc_subchannel_count(mut self, v: usize) -> Self {
143        self.config.grpc_subchannel_count = Some(v);
144        self
145    }
146}
147
148#[cfg(test)]
149mod tests {
150    use super::*;
151    use google_cloud_auth::credentials::anonymous::Builder as Anonymous;
152
153    #[test]
154    fn defaults() {
155        let builder = ClientBuilder::new();
156        assert!(builder.config.endpoint.is_none(), "{:?}", builder.config);
157        assert!(builder.config.cred.is_none(), "{:?}", builder.config);
158        assert!(
159            builder.config.universe_domain.is_none(),
160            "{:?}",
161            builder.config
162        );
163        assert!(
164            builder.config.grpc_subchannel_count.is_none(),
165            "{:?}",
166            builder.config
167        );
168    }
169
170    #[test]
171    fn setters() {
172        let builder = ClientBuilder::new()
173            .with_endpoint("test-endpoint.com")
174            .with_universe_domain("test-ud.com")
175            .with_credentials(Anonymous::new().build())
176            .with_grpc_subchannel_count(16);
177        assert_eq!(
178            builder.config.endpoint,
179            Some("test-endpoint.com".to_string())
180        );
181        assert_eq!(
182            builder.config.universe_domain,
183            Some("test-ud.com".to_string())
184        );
185        assert!(builder.config.cred.is_some(), "{:?}", builder.config);
186        assert_eq!(builder.config.grpc_subchannel_count, Some(16));
187    }
188}