use crate::entities::{
channel::{Channel, ChannelName},
user::User,
};
use std::{collections::HashMap, net::SocketAddr};
use actix::{io::FramedWrite, prelude::*};
use titanirc_types::RegisteredNick;
use tokio::net::TcpStream;
use tokio_util::codec::FramedRead;
pub struct Server {
pub channels: HashMap<ChannelName, Addr<Channel>>,
}
impl Server {
pub fn new() -> Self {
Self {
channels: HashMap::new(),
}
}
}
impl Actor for Server {
type Context = Context<Self>;
}
#[derive(Message)]
#[rtype(result = "()")]
pub struct Connection(pub TcpStream, pub SocketAddr);
impl Handler<Connection> for Server {
type Result = ();
fn handle(&mut self, Connection(stream, remote): Connection, server_ctx: &mut Self::Context) {
println!("Accepted connection from {}", remote);
User::create(move |ctx| {
let nick = RegisteredNick::new();
let (read, write) = tokio::io::split(stream);
let read = FramedRead::new(read, titanirc_codec::Decoder);
let write = FramedWrite::new(
write,
titanirc_codec::Encoder::new("my.cool.server", nick.clone()),
ctx,
);
ctx.add_stream(read);
User::new(server_ctx.address(), write, nick)
});
}
}
impl Handler<crate::entities::channel::events::Join> for Server {
type Result = ();
fn handle(
&mut self,
msg: crate::entities::channel::events::Join,
_ctx: &mut Self::Context,
) -> Self::Result {
#[allow(clippy::option_if_let_else)]
let channel = if let Some(channel) = self.channels.get(&msg.channel_name[..]) {
channel
} else {
let channel_name = ChannelName::new(msg.channel_name.clone());
let channel = Channel::create(|_ctx| Channel::new(channel_name.clone()));
self.channels.entry(channel_name).or_insert(channel)
};
channel.do_send(msg);
}
}
impl Handler<crate::entities::common_events::UserMessage> for Server {
type Result = ();
fn handle(
&mut self,
_msg: crate::entities::common_events::UserMessage,
_ctx: &mut Self::Context,
) -> Self::Result {
todo!()
}
}