From b9116667db096e098f6df4fd2d061242eef6ad4e Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Mon, 1 Feb 2021 18:39:19 +0000 Subject: [PATCH] Delegate message sending to a MessageDestination --- titanirc-server/src/entities/channel/mod.rs | 1 + titanirc-server/src/entities/mod.rs | 2 +- titanirc-server/src/entities/user/commands.rs | 5 ++++- titanirc-server/src/entities/user/mod.rs | 2 +- titanirc-server/src/server.rs | 42 +++++++++++++++++++++++++++++++++++------- titanirc-types/src/primitives.rs | 39 ++++++++++++++++++++++++--------------- 6 files changed, 66 insertions(+), 25 deletions(-) diff --git a/titanirc-server/src/entities/channel/mod.rs b/titanirc-server/src/entities/channel/mod.rs index 6626c03..b7a503f 100644 --- a/titanirc-server/src/entities/channel/mod.rs +++ b/titanirc-server/src/entities/channel/mod.rs @@ -26,6 +26,7 @@ impl Channel { } } + // TODO: add a flag not to broadcast messages to the source so PRIVMSGs dont get duplicated fn broadcast_message(&self, msg: M) -> impl Future where M: Message + Send + Sync, diff --git a/titanirc-server/src/entities/mod.rs b/titanirc-server/src/entities/mod.rs index 4e9e097..1b5829a 100644 --- a/titanirc-server/src/entities/mod.rs +++ b/titanirc-server/src/entities/mod.rs @@ -8,7 +8,7 @@ pub mod common_events { #[rtype(result = "")] pub struct Message { pub from: String, - pub to: String, + pub to: titanirc_types::Receiver<'static>, pub message: String, } } diff --git a/titanirc-server/src/entities/user/commands.rs b/titanirc-server/src/entities/user/commands.rs index c2a82fb..0e00f9d 100644 --- a/titanirc-server/src/entities/user/commands.rs +++ b/titanirc-server/src/entities/user/commands.rs @@ -1,3 +1,5 @@ +//! Handlers for commands originating from a user. + use std::time::Instant; use actix::{Actor, AsyncContext, StreamHandler, WrapFuture}; @@ -61,6 +63,7 @@ impl CommandHandler> for super::User { let ctx_addr = ctx.address(); let nick = nick.clone(); + // TODO: needs to send MODE & NAMES (353, 366) ctx.spawn( async move { server_addr @@ -146,7 +149,7 @@ impl CommandHandler> for super::User { if let Some(nick) = &self.nick { let msg = crate::entities::common_events::Message { from: nick.clone(), // TODO: this need to be a full user string i think - to: receiver.to_string(), + to: receiver, message: free_text.to_string(), }; diff --git a/titanirc-server/src/entities/user/mod.rs b/titanirc-server/src/entities/user/mod.rs index 0bce0fb..9de081f 100644 --- a/titanirc-server/src/entities/user/mod.rs +++ b/titanirc-server/src/entities/user/mod.rs @@ -97,7 +97,7 @@ impl actix::Handler> for User { PrivmsgCommand { _phantom: std::marker::PhantomData, free_text: FreeText(msg.message.as_bytes().into()), - receiver: Receiver::Channel(Channel(msg.to.as_bytes().into())), + receiver: msg.to.clone(), } .into(), )); diff --git a/titanirc-server/src/server.rs b/titanirc-server/src/server.rs index e97d74e..3002f37 100644 --- a/titanirc-server/src/server.rs +++ b/titanirc-server/src/server.rs @@ -3,6 +3,7 @@ use crate::entities::{channel::Channel, user::User}; use std::{collections::HashMap, net::SocketAddr}; use actix::{io::FramedWrite, prelude::*}; +use titanirc_types::Receiver; use tokio::net::TcpStream; use tokio_util::codec::FramedRead; @@ -95,15 +96,42 @@ impl Handler for Server { msg: crate::entities::common_events::Message, ctx: &mut Self::Context, ) -> Self::Result { - eprintln!("to: {}", msg.to); + let dest = MessageDestination::get_destination_from_receiver(&self, &msg.to).unwrap(); + dest.send(ctx, msg); + } +} - let channel = self.channels.get(&msg.to).unwrap().clone(); +pub enum MessageDestination<'a> { + User(&'a Server, Addr), + Channel(&'a Server, Addr), +} - ctx.spawn( - async move { - channel.send(msg).await.unwrap(); +impl<'a> MessageDestination<'a> { + pub fn get_destination_from_receiver<'b>( + server: &'a Server, + receiver: &Receiver<'b>, + ) -> Option { + match receiver { + Receiver::Channel(c) => server + .channels + .get(&c.to_string()) + .cloned() + .map(move |c| Self::Channel(server, c)), + Receiver::User(_u) => todo!(), + } + } + + pub fn send(self, ctx: &mut Context, msg: crate::entities::common_events::Message) { + match self { + Self::Channel(actor, channel) => { + ctx.spawn( + async move { + channel.send(msg).await.unwrap(); + } + .into_actor(actor), + ); } - .into_actor(self), - ); + Self::User(_actor, _u) => todo!(), + } } } diff --git a/titanirc-types/src/primitives.rs b/titanirc-types/src/primitives.rs index 40490d1..0be35dc 100644 --- a/titanirc-types/src/primitives.rs +++ b/titanirc-types/src/primitives.rs @@ -32,6 +32,15 @@ impl From for BytesCow<'_> { } } +impl Clone for BytesCow<'_> { + fn clone(&self) -> Self { + Self::Owned(match self { + Self::Owned(b) => b.clone(), + Self::Borrowed(b) => Bytes::copy_from_slice(b), + }) + } +} + impl std::ops::Deref for BytesCow<'_> { type Target = [u8]; @@ -161,32 +170,32 @@ impl ValidatingParser for Special { } } -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct Username<'a>(pub BytesCow<'a>); space_terminated_primitive!(Username<'_>); noop_validator!(Username<'_>); -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct Mode<'a>(pub BytesCow<'a>); space_terminated_primitive!(Mode<'_>); noop_validator!(Mode<'_>); -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct HostName<'a>(pub BytesCow<'a>); space_terminated_primitive!(HostName<'_>); noop_validator!(HostName<'_>); -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct ServerName<'a>(pub BytesCow<'a>); space_terminated_primitive!(ServerName<'_>); noop_validator!(ServerName<'_>); -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct RealName<'a>(pub BytesCow<'a>); space_terminated_primitive!(RealName<'_>); noop_validator!(RealName<'_>); -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct Nick<'a>(pub BytesCow<'a>); space_terminated_primitive!(Nick<'_>); @@ -208,17 +217,17 @@ impl ValidatingParser for Nick<'_> { } } -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct Channel<'a>(pub BytesCow<'a>); space_terminated_primitive!(Channel<'_>); noop_validator!(Channel<'_>); -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct FreeText<'a>(pub BytesCow<'a>); free_text_primitive!(FreeText<'_>); noop_validator!(FreeText<'_>); -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct Nicks<'a>(pub Vec>); space_delimited_display!(Nicks<'_>); @@ -236,7 +245,7 @@ impl PrimitiveParser for Nicks<'_> { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct RightsPrefixedNick<'a>(pub Rights, pub Nick<'a>); impl std::fmt::Display for RightsPrefixedNick<'_> { @@ -246,11 +255,11 @@ impl std::fmt::Display for RightsPrefixedNick<'_> { } } -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct RightsPrefixedNicks<'a>(pub Vec>); space_delimited_display!(RightsPrefixedNicks<'_>); -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct RightsPrefixedChannel<'a>(pub Rights, pub Nick<'a>); impl std::fmt::Display for RightsPrefixedChannel<'_> { @@ -260,11 +269,11 @@ impl std::fmt::Display for RightsPrefixedChannel<'_> { } } -#[derive(Debug, Deref, From)] +#[derive(Debug, Deref, Clone, From)] pub struct RightsPrefixedChannels<'a>(pub Vec>); space_delimited_display!(RightsPrefixedChannels<'_>); -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] pub enum Rights { Op, Voice, @@ -279,7 +288,7 @@ impl std::fmt::Display for Rights { } } -#[derive(Debug, From)] +#[derive(Debug, From, Clone)] pub enum Receiver<'a> { User(Nick<'a>), Channel(Channel<'a>), -- libgit2 1.7.2