#![macro_use]
use std::{borrow::Cow, fmt::Display};
pub use ya_gcp::{
self as gcp,
grpc::StatusCodeSet,
pubsub::{
AcknowledgeError, AcknowledgeToken, BuildError, Error as PubSubError, MakeConnection,
ModifyAcknowledgeError, PubSubConfig, PubSubRetryCheck, SinkError,
StreamSubscriptionConfig, Uri,
},
retry_policy, AuthFlow, ClientBuilderConfig, Connect, CreateBuilderError, DefaultConnector,
ServiceAccountAuth,
};
type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
macro_rules! match_fields {
(
$target:path =>
$(#[$struct_attr:meta])*
pub struct $struct_name:ident $(<$struct_generics:tt>)? {
$(
$(#[$field_attr:meta])*
pub $field_name:ident : $field_type:ty,
)*$(,)?
@except:
$(
$target_except_field:ident,
)*$(,)?
}
) => {
$(#[$struct_attr])*
#[cfg_attr(docsrs, cfg_attr(docsrs,
doc = "", // newline
doc = concat!("This is a more ergonomic wrapper over [`", stringify!($target), "`]")
))]
#[cfg_attr(not(docsrs), allow(missing_docs))]
pub struct $struct_name $(<$struct_generics>)? {
$(
#[cfg_attr(docsrs, cfg_attr(docsrs, doc = concat!(
"See [`", stringify!($field_name), "`]",
"(", stringify!($target), "::", stringify!($field_name), ")"
)))]
$(#[$field_attr])*
pub $field_name : $field_type,
)*
}
impl$(<$struct_generics>)? $struct_name $(<$struct_generics>)? {
const _MATCH_CHECK: () = {
match None {
Some($target {
$(
$field_name: _,
)*
$(
$target_except_field: _,
)*
}) => {},
None => {}
};
};
}
};
}
mod consumer;
mod publisher;
pub use consumer::*;
pub use publisher::*;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TopicName<'s>(Cow<'s, str>);
impl<'s> TopicName<'s> {
pub fn new(name: impl Into<Cow<'s, str>>) -> Self {
Self(name.into())
}
fn into_project_topic_name(
self,
project_name: impl Display,
) -> ya_gcp::pubsub::ProjectTopicName {
ya_gcp::pubsub::ProjectTopicName::new(
project_name,
std::format_args!("hedwig-{topic}", topic = self.0),
)
}
}
pub struct ClientBuilder<C = DefaultConnector> {
inner: ya_gcp::ClientBuilder<C>,
pubsub_config: PubSubConfig,
}
impl ClientBuilder {
pub async fn new(
config: ClientBuilderConfig,
pubsub_config: PubSubConfig,
) -> Result<Self, CreateBuilderError> {
Ok(ClientBuilder {
inner: ya_gcp::ClientBuilder::new(config).await?,
pubsub_config,
})
}
}
impl<C> ClientBuilder<C>
where
C: Connect + Clone + Send + Sync + 'static,
{
pub async fn with_connector(
config: ClientBuilderConfig,
pubsub_config: PubSubConfig,
connector: C,
) -> Result<Self, CreateBuilderError> {
Ok(ClientBuilder {
inner: ya_gcp::ClientBuilder::with_connector(config, connector).await?,
pubsub_config,
})
}
}
impl<C> ClientBuilder<C>
where
C: MakeConnection<Uri> + Connect + Clone + Send + Sync + 'static,
C::Connection: Unpin + Send + 'static,
C::Future: Send + 'static,
BoxError: From<C::Error>,
{
pub async fn build_consumer(
&self,
project: impl Into<String>,
queue: impl Into<String>,
) -> Result<ConsumerClient<C>, BuildError> {
Ok(ConsumerClient::new(
self.inner
.build_pubsub_subscriber(self.pubsub_config.clone())
.await?,
project.into(),
queue.into(),
))
}
pub async fn build_publisher(
&self,
project: impl Into<String>,
publisher_id: impl Into<String>,
) -> Result<PublisherClient<C>, BuildError> {
Ok(PublisherClient::new(
self.inner
.build_pubsub_publisher(self.pubsub_config.clone())
.await?,
project.into(),
publisher_id.into(),
))
}
}