gnostr_relay/
extension.rs

1use crate::{
2    message::{ClientMessage, OutgoingMessage},
3    setting::SettingWrapper,
4    Session,
5};
6use actix_web::web::ServiceConfig;
7
8pub enum ExtensionMessageResult {
9    /// Continue run the next extension message method, the server takes over finally.
10    Continue(ClientMessage),
11    /// Stop run the next, send outgoing message to client.
12    Stop(OutgoingMessage),
13    /// Stop run the next, does not send any messages to the client.
14    Ignore,
15}
16
17impl From<OutgoingMessage> for ExtensionMessageResult {
18    fn from(value: OutgoingMessage) -> Self {
19        Self::Stop(value)
20    }
21}
22
23/// Extension for user session
24pub trait Extension: Send + Sync {
25    fn name(&self) -> &'static str;
26
27    /// Execute when added to extension list and setting reload
28    #[allow(unused_variables)]
29    fn setting(&mut self, setting: &SettingWrapper) {}
30
31    /// config actix web service
32    #[allow(unused_variables)]
33    fn config_web(&mut self, cfg: &mut ServiceConfig) {}
34
35    /// Execute after a user connect
36    #[allow(unused_variables)]
37    fn connected(&self, session: &mut Session, ctx: &mut <Session as actix::Actor>::Context) {}
38
39    /// Execute when connection lost
40    #[allow(unused_variables)]
41    fn disconnected(&self, session: &mut Session, ctx: &mut <Session as actix::Actor>::Context) {}
42
43    /// Execute when message incoming
44    #[allow(unused_variables)]
45    fn message(
46        &self,
47        msg: ClientMessage,
48        session: &mut Session,
49        ctx: &mut <Session as actix::Actor>::Context,
50    ) -> ExtensionMessageResult {
51        ExtensionMessageResult::Continue(msg)
52    }
53}
54
55/// extensions
56#[derive(Default)]
57pub struct Extensions {
58    list: Vec<Box<dyn Extension>>,
59}
60
61impl Extensions {
62    pub fn add<E: Extension + 'static>(&mut self, ext: E) {
63        self.list.push(Box::new(ext));
64    }
65
66    pub fn call_setting(&mut self, setting: &SettingWrapper) {
67        for ext in &mut self.list {
68            ext.setting(setting);
69        }
70    }
71
72    pub fn call_config_web(&mut self, cfg: &mut ServiceConfig) {
73        for ext in &mut self.list {
74            ext.config_web(cfg);
75        }
76    }
77
78    pub fn call_connected(
79        &self,
80        session: &mut Session,
81        ctx: &mut <Session as actix::Actor>::Context,
82    ) {
83        for ext in &self.list {
84            ext.connected(session, ctx);
85        }
86    }
87
88    pub fn call_disconnected(
89        &self,
90        session: &mut Session,
91        ctx: &mut <Session as actix::Actor>::Context,
92    ) {
93        for ext in &self.list {
94            ext.disconnected(session, ctx);
95        }
96    }
97
98    pub fn call_message(
99        &self,
100        msg: ClientMessage,
101        session: &mut Session,
102        ctx: &mut <Session as actix::Actor>::Context,
103    ) -> ExtensionMessageResult {
104        let mut msg = msg;
105        for ext in &self.list {
106            match ext.message(msg, session, ctx) {
107                ExtensionMessageResult::Continue(m) => {
108                    msg = m;
109                }
110                ExtensionMessageResult::Stop(o) => {
111                    return ExtensionMessageResult::Stop(o);
112                }
113                ExtensionMessageResult::Ignore => {
114                    return ExtensionMessageResult::Ignore;
115                }
116            };
117        }
118        ExtensionMessageResult::Continue(msg)
119    }
120}