pub mod events;
use actix::prelude::*;
use bytes::Bytes;
use derive_more::Deref;
use std::{collections::HashMap, sync::Arc};
use crate::entities::user::{User, UserUuid};
#[derive(Clone, Debug, Deref, Eq, PartialEq, Hash)]
#[allow(clippy::module_name_repetitions)]
pub struct ChannelName(Bytes);
impl ChannelName {
pub fn new(name: Bytes) -> Self {
Self(name)
}
}
impl std::borrow::Borrow<[u8]> for ChannelName {
fn borrow(&self) -> &[u8] {
&self.0[..]
}
}
#[derive(Message)]
#[rtype(result = "")]
pub struct Handle {
pub channel_name: ChannelName,
pub message: actix::Recipient<super::common_events::ChannelMessage>,
}
pub struct Channel {
pub channel_name: ChannelName,
pub members: HashMap<UserUuid, Addr<User>>,
}
impl Channel {
pub fn new(channel_name: ChannelName) -> Self {
Self {
channel_name,
members: HashMap::new(),
}
}
fn broadcast_message<M>(&self, skip_sender: Option<UserUuid>, msg: Arc<M>)
where
M: Message + Send + Sync,
M::Result: Send,
Arc<M>: 'static,
User: Handler<Arc<M>>,
{
for (uuid, member) in &self.members {
if let Some(skip_sender) = &skip_sender {
if skip_sender == uuid {
continue;
}
}
member.do_send(msg.clone());
}
}
}
impl Actor for Channel {
type Context = Context<Self>;
}
impl actix::Handler<events::Join> for Channel {
type Result = ();
fn handle(&mut self, event: events::Join, ctx: &mut Self::Context) -> Self::Result {
self.members.insert(event.user_uuid, event.user.clone());
let event = Arc::new(event);
self.broadcast_message(None, Arc::clone(&event));
event.user.do_send(Handle {
channel_name: self.channel_name.clone(),
message: ctx.address().recipient(),
})
}
}
impl actix::Handler<super::common_events::ChannelMessage> for Channel {
type Result = ();
fn handle(
&mut self,
msg: super::common_events::ChannelMessage,
_ctx: &mut Self::Context,
) -> Self::Result {
self.broadcast_message(Some(msg.0.user_uuid), Arc::new(msg));
}
}