use std::{error::Error, fmt::Display, sync::Arc};
use async_trait::async_trait;
use crate::communication::RegistrationError;
use crate::core::usubscription::SubscriptionStatus;
use crate::{UListener, UStatus, UUri};
use super::{CallOptions, UPayload};
#[derive(Debug)]
pub enum PubSubError {
InvalidArgument(String),
PublishError(UStatus),
}
#[cfg(not(tarpaulin_include))]
impl Display for PubSubError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PubSubError::InvalidArgument(s) => f.write_str(s.as_str()),
PubSubError::PublishError(s) => {
f.write_fmt(format_args!("failed to publish message: {s}"))
}
}
}
}
impl Error for PubSubError {}
#[async_trait]
pub trait Publisher: Send + Sync {
async fn publish(
&self,
resource_id: u16,
call_options: CallOptions,
payload: Option<UPayload>,
) -> Result<(), PubSubError>;
}
#[cfg_attr(any(test, feature = "test-util"), mockall::automock)]
pub trait SubscriptionChangeHandler: Send + Sync {
fn on_subscription_change(&self, topic: UUri, new_status: SubscriptionStatus);
}
#[async_trait]
pub trait Subscriber: Send + Sync {
async fn subscribe(
&self,
topic: &UUri,
handler: Arc<dyn UListener>,
subscription_change_handler: Option<Arc<dyn SubscriptionChangeHandler>>,
) -> Result<(), RegistrationError>;
async fn unsubscribe(
&self,
topic: &UUri,
handler: Arc<dyn UListener>,
) -> Result<(), RegistrationError>;
}