#
google_cloud_pubsub/publisher/
client.rs

    1// Copyright 2025 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::publisher::publisher::PublisherBuilder;
    16
    17/// Creates [`Publisher`](super::publisher::Publisher) instances.
    18///
    19/// This is the main entry point for the publisher API. A single `Client`
    20/// can be used to create multiple `Publisher` clients for different topics.
    21/// It manages the underlying gRPC connection and authentication.
    22///
    23/// # Example
    24///
    25/// ```
    26/// # async fn sample() -> anyhow::Result<()> {
    27/// # use google_cloud_pubsub::client::Client;
    28/// # use google_cloud_pubsub::model::PubsubMessage;
    29///
    30/// // Create a client.
    31/// let client = Client::builder().build().await?;
    32///
    33/// // Create a publisher for a specific topic.
    34/// let publisher = client.publisher("projects/my-project/topics/my-topic").build();
    35///
    36/// // Publish a message.
    37/// let handle = publisher.publish(PubsubMessage::new().set_data("hello world"));
    38/// let message_id = handle.await?;
    39/// println!("Message sent with ID: {}", message_id);
    40/// # Ok(())
    41/// # }
    42/// ```
    43#[derive(Clone, Debug)]
    44pub struct Client {
    45    pub(crate) inner: crate::generated::gapic_dataplane::client::Publisher,
    46}
    47
    48/// A builder for [Client].
    49///
    50/// ```
    51/// # async fn sample() -> anyhow::Result<()> {
    52/// # use google_cloud_pubsub::*;
    53/// # use builder::publisher::ClientBuilder;
    54/// # use client::Client;
    55/// let builder: ClientBuilder = Client::builder();
    56/// let client = builder
    57///     .with_endpoint("https://pubsub.googleapis.com")
    58///     .build().await?;
    59/// # Ok(()) }
    60/// ```
    61pub type ClientBuilder =
    62    gax::client_builder::ClientBuilder<client_builder::Factory, gaxi::options::Credentials>;
    63
    64pub(crate) mod client_builder {
    65    use super::Client;
    66
    67    pub struct Factory;
    68    impl gax::client_builder::internal::ClientFactory for Factory {
    69        type Client = Client;
    70        type Credentials = gaxi::options::Credentials;
    71        #[allow(unused_mut)]
    72        async fn build(
    73            self,
    74            mut config: gaxi::options::ClientConfig,
    75        ) -> gax::client_builder::Result<Self::Client> {
    76            // TODO(#3019): Pubsub default retry policy goes here.
    77            Self::Client::new(config).await
    78        }
    79    }
    80}
    81
    82impl Client {
    83    /// Returns a builder for [Client].
    84    ///
    85    /// ```no_run
    86    /// # tokio_test::block_on(async {
    87    /// # use google_cloud_pubsub::client::Client;
    88    /// let client = Client::builder().build().await?;
    89    /// # gax::client_builder::Result::<()>::Ok(()) });
    90    /// ```
    91    pub fn builder() -> ClientBuilder {
    92        gax::client_builder::internal::new_builder(client_builder::Factory)
    93    }
    94
    95    /// Creates a new Pub/Sub publisher client with the given configuration.
    96    pub(crate) async fn new(
    97        config: gaxi::options::ClientConfig,
    98    ) -> Result<Self, gax::client_builder::Error> {
    99        let inner = crate::generated::gapic_dataplane::client::Publisher::new(config).await?;
    100        std::result::Result::Ok(Self { inner })
    101    }
    102
    103    /// Creates a new `Publisher` for a given topic.
    104    ///
    105    /// ```
    106    /// # async fn sample() -> anyhow::Result<()> {
    107    /// # use google_cloud_pubsub::*;
    108    /// # use builder::publisher::ClientBuilder;
    109    /// # use client::Client;
    110    /// # use model::PubsubMessage;
    111    /// let client = Client::builder().build().await?;
    112    /// let publisher = client.publisher("projects/my-project/topics/my-topic").build();
    113    /// let message_id = publisher.publish(PubsubMessage::new().set_data("Hello, World")).await?;
    114    /// # Ok(()) }
    115    /// ```
    116    pub fn publisher<T>(&self, topic: T) -> PublisherBuilder
    117    where
    118        T: Into<String>,
    119    {
    120        PublisherBuilder::new(self.inner.clone(), topic.into())
    121    }
    122}
    123
    124#[cfg(test)]
    125mod tests {
    126    use super::Client;
    127
    128    #[tokio::test]
    129    async fn builder() -> anyhow::Result<()> {
    130        let client = Client::builder()
    131            .with_credentials(auth::credentials::anonymous::Builder::new().build())
    132            .build()
    133            .await?;
    134        let _ = client.publisher("projects/my-project/topics/my-topic".to_string());
    135        Ok(())
    136    }
    137}