use serde_json::value::RawValue;
use tokio::sync::mpsc;
use tracing::error;
use crate::RpcSend;
#[derive(thiserror::Error, Debug)]
pub enum NotifyError {
#[error("failed to serialize notification: {0}")]
Serde(#[from] serde_json::Error),
#[error("notification channel closed")]
Send(#[from] mpsc::error::SendError<Box<RawValue>>),
}
#[derive(Debug, Clone, Default)]
pub struct HandlerCtx {
pub(crate) notifications: Option<mpsc::Sender<Box<RawValue>>>,
}
impl From<mpsc::Sender<Box<RawValue>>> for HandlerCtx {
fn from(notifications: mpsc::Sender<Box<RawValue>>) -> Self {
Self {
notifications: Some(notifications),
}
}
}
impl HandlerCtx {
pub const fn new() -> Self {
Self {
notifications: None,
}
}
pub const fn with_notifications(notifications: mpsc::Sender<Box<RawValue>>) -> Self {
Self {
notifications: Some(notifications),
}
}
pub const fn notifications(&self) -> Option<&mpsc::Sender<Box<RawValue>>> {
self.notifications.as_ref()
}
pub fn notifications_enabled(&self) -> bool {
self.notifications
.as_ref()
.map(|tx| !tx.is_closed())
.unwrap_or_default()
}
pub async fn notify<T: RpcSend>(&self, t: &T) -> Result<(), NotifyError> {
if let Some(notifications) = self.notifications.as_ref() {
let ser = serde_json::to_string(t)?;
let rv = serde_json::value::to_raw_value(&ser)?;
notifications.send(rv).await?;
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct HandlerArgs {
pub ctx: HandlerCtx,
pub req: crate::types::Request,
}