kaspa_notify/
connection.rs

1use 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    /// Close the connection, ignoring the channel type
46    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}