2023-04-28 12:31:59 +02:00
|
|
|
use crate::{api::WebSocketEvent, errors::ObserverError};
|
2023-04-27 22:38:41 +02:00
|
|
|
|
2023-04-16 23:03:24 +02:00
|
|
|
#[derive(Debug)]
|
2023-04-27 17:57:10 +02:00
|
|
|
pub struct Gateway {}
|
|
|
|
|
2023-04-28 12:31:59 +02:00
|
|
|
pub trait Observer<T: WebSocketEvent> {
|
|
|
|
fn update(&self, data: &T);
|
2023-04-27 17:57:10 +02:00
|
|
|
}
|
|
|
|
|
2023-04-28 12:31:59 +02:00
|
|
|
pub struct GatewayEvent<'a, T: WebSocketEvent> {
|
|
|
|
observers: Vec<&'a dyn Observer<T>>,
|
|
|
|
pub event_data: T,
|
2023-04-27 22:29:07 +02:00
|
|
|
pub is_observed: bool,
|
2023-04-27 17:57:10 +02:00
|
|
|
}
|
|
|
|
|
2023-04-28 12:31:59 +02:00
|
|
|
impl<'a, T: WebSocketEvent> GatewayEvent<'a, T> {
|
|
|
|
fn new(event_data: T) -> Self {
|
2023-04-27 17:57:10 +02:00
|
|
|
Self {
|
2023-04-27 22:29:07 +02:00
|
|
|
is_observed: false,
|
2023-04-27 17:57:10 +02:00
|
|
|
observers: Vec::new(),
|
2023-04-28 12:31:59 +02:00
|
|
|
event_data,
|
2023-04-27 17:57:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-27 22:29:07 +02:00
|
|
|
pub fn is_observed(&self) -> bool {
|
|
|
|
self.is_observed
|
|
|
|
}
|
|
|
|
|
2023-04-28 12:31:59 +02:00
|
|
|
pub fn subscribe(&mut self, observable: &'a dyn Observer<T>) -> Option<ObserverError> {
|
2023-04-27 22:29:07 +02:00
|
|
|
if self.is_observed {
|
2023-04-27 22:38:41 +02:00
|
|
|
return Some(ObserverError::AlreadySubscribedError);
|
2023-04-27 22:29:07 +02:00
|
|
|
}
|
|
|
|
self.is_observed = true;
|
2023-04-27 22:38:41 +02:00
|
|
|
self.observers.push(observable);
|
|
|
|
None
|
2023-04-27 17:57:10 +02:00
|
|
|
}
|
|
|
|
|
2023-04-28 12:31:59 +02:00
|
|
|
pub fn unsubscribe(&mut self, observable: &'a dyn Observer<T>) {
|
|
|
|
// .retain()'s closure retains only those elements of the vector, which have a different
|
|
|
|
// pointer value than observable.
|
|
|
|
self.observers.retain(|obs| !std::ptr::eq(*obs, observable));
|
|
|
|
self.is_observed = !self.observers.is_empty();
|
2023-04-27 22:29:07 +02:00
|
|
|
return;
|
2023-04-27 17:57:10 +02:00
|
|
|
}
|
|
|
|
|
2023-04-28 12:31:59 +02:00
|
|
|
fn update_data(&mut self, new_event_data: T) {
|
|
|
|
self.event_data = new_event_data;
|
2023-04-27 17:57:10 +02:00
|
|
|
self.notify();
|
|
|
|
}
|
|
|
|
|
2023-04-27 22:29:07 +02:00
|
|
|
fn notify(&self) {
|
2023-04-27 17:57:10 +02:00
|
|
|
for observer in &self.observers {
|
2023-04-28 12:31:59 +02:00
|
|
|
observer.update(&self.event_data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
2023-04-28 12:39:58 +02:00
|
|
|
mod example {
|
2023-04-28 12:31:59 +02:00
|
|
|
use super::*;
|
|
|
|
use crate::api::types::GatewayResume;
|
|
|
|
|
|
|
|
struct Consumer;
|
|
|
|
impl Observer<GatewayResume> for Consumer {
|
|
|
|
fn update(&self, data: &GatewayResume) {
|
|
|
|
println!("{}", data.token)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_observer_behaviour() {
|
|
|
|
let mut event = GatewayEvent::new(GatewayResume {
|
|
|
|
token: "start".to_string(),
|
|
|
|
session_id: "start".to_string(),
|
|
|
|
seq: "start".to_string(),
|
|
|
|
});
|
|
|
|
|
|
|
|
let new_data = GatewayResume {
|
|
|
|
token: "token_3276ha37am3".to_string(),
|
|
|
|
session_id: "89346671230".to_string(),
|
|
|
|
seq: "3".to_string(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let consumer = Consumer;
|
|
|
|
|
|
|
|
event.subscribe(&consumer);
|
|
|
|
|
|
|
|
event.notify();
|
|
|
|
|
|
|
|
event.update_data(new_data);
|
|
|
|
|
|
|
|
let second_consumer = Consumer;
|
|
|
|
|
|
|
|
match event.subscribe(&second_consumer) {
|
2023-04-28 12:39:58 +02:00
|
|
|
None => assert!(false),
|
2023-04-28 12:31:59 +02:00
|
|
|
Some(err) => println!("You cannot subscribe twice: {}", err),
|
2023-04-27 17:57:10 +02:00
|
|
|
}
|
|
|
|
}
|
2023-04-25 17:21:27 +02:00
|
|
|
}
|