Skip to main content

google_cloud_pubsub/subscriber/
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 super::client::Subscriber;
16use crate::ClientBuilderResult as BuilderResult;
17use gaxi::options::ClientConfig;
18use google_cloud_auth::credentials::Credentials;
19
20/// A builder for [Subscriber].
21///
22/// # Example
23/// ```
24/// # use google_cloud_pubsub::client::Subscriber;
25/// # async fn sample() -> anyhow::Result<()> {
26/// let builder = Subscriber::builder();
27/// let client = builder
28///     .with_endpoint("https://pubsub.googleapis.com")
29///     .build()
30///     .await?;
31/// # Ok(()) }
32/// ```
33pub struct ClientBuilder {
34    pub(super) config: ClientConfig,
35}
36
37impl ClientBuilder {
38    pub(super) fn new() -> Self {
39        Self {
40            config: ClientConfig::default(),
41        }
42    }
43
44    /// Creates a new client.
45    ///
46    /// # Example
47    /// ```
48    /// # use google_cloud_pubsub::client::Subscriber;
49    /// # async fn sample() -> anyhow::Result<()> {
50    /// let client = Subscriber::builder().build().await?;
51    /// # Ok(()) }
52    /// ```
53    pub async fn build(self) -> BuilderResult<Subscriber> {
54        Subscriber::new(self).await
55    }
56
57    /// Sets the endpoint.
58    ///
59    /// # Example
60    /// ```
61    /// # use google_cloud_pubsub::client::Subscriber;
62    /// # async fn sample() -> anyhow::Result<()> {
63    /// let client = Subscriber::builder()
64    ///     .with_endpoint("https://private.googleapis.com")
65    ///     .build()
66    ///     .await?;
67    /// # Ok(()) }
68    /// ```
69    pub fn with_endpoint<V: Into<String>>(mut self, v: V) -> Self {
70        self.config.endpoint = Some(v.into());
71        self
72    }
73
74    /// Configures the authentication credentials.
75    ///
76    /// More information about valid credentials types can be found in the
77    /// [google-cloud-auth] crate documentation.
78    ///
79    /// # Example
80    /// ```
81    /// # use google_cloud_pubsub::client::Subscriber;
82    /// # async fn sample() -> anyhow::Result<()> {
83    /// use google_cloud_auth::credentials::mds;
84    /// let client = Subscriber::builder()
85    ///     .with_credentials(
86    ///         mds::Builder::default()
87    ///             .with_scopes(["https://www.googleapis.com/auth/cloud-platform.read-only"])
88    ///             .build()?)
89    ///     .build()
90    ///     .await?;
91    /// # Ok(()) }
92    /// ```
93    ///
94    /// [google-cloud-auth]: https://docs.rs/google-cloud-auth
95    pub fn with_credentials<V: Into<Credentials>>(mut self, v: V) -> Self {
96        self.config.cred = Some(v.into());
97        self
98    }
99
100    /// Configure the number of subchannels used by the client.
101    ///
102    /// # Example
103    /// ```
104    /// # use google_cloud_pubsub::client::Subscriber;
105    /// # async fn sample() -> anyhow::Result<()> {
106    /// let count = std::thread::available_parallelism()?.get();
107    /// let client = Subscriber::builder()
108    ///     .with_grpc_subchannel_count(count)
109    ///     .build()
110    ///     .await?;
111    /// # Ok(()) }
112    /// ```
113    ///
114    /// gRPC-based clients may exhibit high latency if many requests need to be
115    /// demuxed over a single HTTP/2 connection (often called a *subchannel* in
116    /// gRPC).
117    ///
118    /// Consider using more subchannels if your application opens many message
119    /// streams. Consider using fewer subchannels if your application needs the
120    /// file descriptors for other purposes.
121    pub fn with_grpc_subchannel_count(mut self, v: usize) -> Self {
122        self.config.grpc_subchannel_count = Some(v);
123        self
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130    use google_cloud_auth::credentials::anonymous::Builder as Anonymous;
131
132    #[test]
133    fn defaults() {
134        let builder = ClientBuilder::new();
135        assert!(builder.config.endpoint.is_none(), "{:?}", builder.config);
136        assert!(builder.config.cred.is_none(), "{:?}", builder.config);
137        assert!(
138            builder.config.grpc_subchannel_count.is_none(),
139            "{:?}",
140            builder.config
141        );
142    }
143
144    #[test]
145    fn setters() {
146        let builder = ClientBuilder::new()
147            .with_endpoint("test-endpoint.com")
148            .with_credentials(Anonymous::new().build())
149            .with_grpc_subchannel_count(16);
150        assert_eq!(
151            builder.config.endpoint,
152            Some("test-endpoint.com".to_string())
153        );
154        assert!(builder.config.cred.is_some(), "{:?}", builder.config);
155        assert_eq!(builder.config.grpc_subchannel_count, Some(16));
156    }
157}