kaspa_notify/
connection.rs1use crate::error::Error;
2use crate::notification::Notification;
3use async_channel::Sender;
4use std::fmt::{Debug, Display};
5use std::hash::Hash;
6
7#[async_trait::async_trait]
8pub trait Connection: Clone + Display + Debug + Send + Sync + 'static {
9 type Notification;
10 type Message: Clone + Send + Sync;
11 type Encoding: Hash + Clone + Eq + PartialEq + Send + Sync;
12 type Error: Into<Error>;
13
14 fn encoding(&self) -> Self::Encoding;
15 fn into_message(notification: &Self::Notification, encoding: &Self::Encoding) -> Self::Message;
16 async fn send(&self, message: Self::Message) -> Result<(), Self::Error>;
17 fn close(&self) -> bool;
18 fn is_closed(&self) -> bool;
19}
20
21#[derive(Clone, Debug)]
22pub enum ChannelType {
23 Closable,
24 Persistent,
25}
26
27#[derive(Clone, Debug)]
28pub struct ChannelConnection<N>
29where
30 N: Notification,
31{
32 name: &'static str,
33 sender: Sender<N>,
34 channel_type: ChannelType,
35}
36
37impl<N> ChannelConnection<N>
38where
39 N: Notification,
40{
41 pub fn new(name: &'static str, sender: Sender<N>, channel_type: ChannelType) -> Self {
42 Self { name, sender, channel_type }
43 }
44
45 pub fn force_close(&self) -> bool {
47 self.sender.close()
48 }
49}
50
51impl<N> Display for ChannelConnection<N>
52where
53 N: Notification,
54{
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 write!(f, "{}", self.name)
57 }
58}
59
60#[derive(Clone, Debug, Hash, Eq, PartialEq, Default)]
61pub enum Unchanged {
62 #[default]
63 Clone = 0,
64}
65
66#[async_trait::async_trait]
67impl<N> Connection for ChannelConnection<N>
68where
69 N: Notification,
70{
71 type Notification = N;
72 type Message = N;
73 type Encoding = Unchanged;
74 type Error = Error;
75
76 fn encoding(&self) -> Self::Encoding {
77 Unchanged::Clone
78 }
79
80 fn into_message(notification: &Self::Notification, _: &Self::Encoding) -> Self::Message {
81 notification.clone()
82 }
83
84 async fn send(&self, message: Self::Message) -> Result<(), Self::Error> {
85 match !self.is_closed() {
86 true => Ok(self.sender.send(message).await?),
87 false => Err(Error::ConnectionClosed),
88 }
89 }
90
91 fn close(&self) -> bool {
92 match self.channel_type {
93 ChannelType::Closable => self.sender.close(),
94 ChannelType::Persistent => false,
95 }
96 }
97
98 fn is_closed(&self) -> bool {
99 self.sender.is_closed()
100 }
101}