use std::sync::Arc;
use actix::prelude::*;
use crate::{entities::user::User, server::Server};
pub mod events {
use crate::entities::user::User;
use actix::prelude::*;
pub type JoinResult = Result<super::Handle, JoinError>;
#[derive(Message)]
#[rtype(result = "JoinResult")]
pub struct Join {
pub channel_name: String,
pub nick: String,
pub user: Addr<User>,
}
#[derive(Debug, thiserror::Error, displaydoc::Display)]
pub enum JoinError {
Mailbox(#[from] actix::MailboxError),
}
#[derive(Message)]
#[rtype(result = "")]
pub struct JoinBroadcast {
pub channel_name: String,
pub nick: String,
}
impl From<Join> for JoinBroadcast {
fn from(
Join {
channel_name, nick, ..
}: Join,
) -> Self {
Self { channel_name, nick }
}
}
}
pub struct Handle {
pub message: actix::Recipient<super::common_events::Message>,
}
pub struct Channel {
pub members: Vec<Addr<User>>,
}
impl Channel {
fn announce_join(&self, join: events::Join) -> impl Future<Output = ()> {
let mut futures = Vec::new();
let broadcast = Arc::new(events::JoinBroadcast::from(join));
for member in &self.members {
futures.push(member.send(broadcast.clone()));
}
async {
futures_util::future::try_join_all(futures).await.unwrap();
}
}
}
impl Actor for Channel {
type Context = Context<Self>;
}
impl actix::Handler<events::Join> for Channel {
type Result = events::JoinResult;
fn handle(&mut self, msg: events::Join, ctx: &mut Self::Context) -> Self::Result {
self.members.push(msg.user.clone());
ctx.spawn(self.announce_join(msg).into_actor(self));
Ok(Handle {
message: ctx.address().recipient(),
})
}
}
impl actix::Handler<super::common_events::Message> for Channel {
type Result = ();
fn handle(
&mut self,
msg: super::common_events::Message,
ctx: &mut Self::Context,
) -> Self::Result {
}
}