use crate::config::ServerConfig;
use crate::middleware::Middleware;
use crate::models::Packet;
use crate::Sender;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use tokio::sync::{Mutex as TokioMutex, RwLock};
pub type SocketId = String;
pub type Channel = String;
pub struct AuthData {
pub is_authenticated: std::sync::atomic::AtomicBool,
pub token: TokioMutex<Option<String>>,
pub user_id: TokioMutex<Option<String>>,
}
pub struct SocketData<S: Sender> {
pub sender: TokioMutex<S>,
pub auth_data: AuthData,
pub last_ping: TokioMutex<std::time::Instant>,
}
pub struct AppState<S: Sender> {
pub sockets: Arc<RwLock<HashMap<SocketId, SocketData<S>>>>,
pub subscriptions: Arc<RwLock<HashMap<Channel, HashSet<SocketId>>>>,
pub config: ServerConfig,
middleware: Arc<Vec<Arc<dyn Middleware>>>,
}
impl<S: Sender> AppState<S> {
pub fn new(config: ServerConfig) -> Self {
AppState {
sockets: Arc::new(RwLock::new(HashMap::new())),
subscriptions: Arc::new(RwLock::new(HashMap::new())),
config,
middleware: Arc::new(vec![]),
}
}
pub fn add_middleware(&mut self, middleware: Arc<dyn Middleware>) {
Arc::get_mut(&mut self.middleware).unwrap().push(middleware);
}
pub(crate) async fn apply_middleware(&self, packet: &mut Packet, socket_id: &SocketId) -> bool {
let sockets = self.sockets.read().await;
if let Some(socket_data) = sockets.get(socket_id) {
for middleware in self.middleware.iter() {
if !middleware.handle(packet, &socket_data.auth_data).await {
return false;
}
}
}
true
}
}
impl<S: Sender> Clone for AppState<S> {
fn clone(&self) -> Self {
AppState {
sockets: self.sockets.clone(),
subscriptions: self.subscriptions.clone(),
config: self.config.clone(),
middleware: self.middleware.clone(),
}
}
fn clone_from(&mut self, source: &Self) {
*self = source.clone()
}
}