Delegate message sending to a MessageDestination
Diff
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(-)
@@ -26,6 +26,7 @@ impl Channel {
}
}
fn broadcast_message<M>(&self, msg: M) -> impl Future<Output = ()>
where
M: Message + Send + Sync,
@@ -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,
}
}
@@ -1,3 +1,5 @@
use std::time::Instant;
use actix::{Actor, AsyncContext, StreamHandler, WrapFuture};
@@ -61,6 +63,7 @@ impl CommandHandler<JoinCommand<'static>> for super::User {
let ctx_addr = ctx.address();
let nick = nick.clone();
ctx.spawn(
async move {
server_addr
@@ -146,7 +149,7 @@ impl CommandHandler<PrivmsgCommand<'static>> for super::User {
if let Some(nick) = &self.nick {
let msg = crate::entities::common_events::Message {
from: nick.clone(), to: receiver.to_string(),
to: receiver,
message: free_text.to_string(),
};
@@ -97,7 +97,7 @@ impl actix::Handler<Arc<crate::entities::common_events::Message>> 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(),
));
@@ -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<crate::entities::common_events::Message> 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<User>),
Channel(&'a Server, Addr<Channel>),
}
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<Self> {
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<Server>, 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!(),
}
}
}
@@ -32,6 +32,15 @@ impl From<BytesWrapper> 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<Nick<'a>>);
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<RightsPrefixedNick<'a>>);
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<RightsPrefixedChannel<'a>>);
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>),