Implement AWAY
Diff
src/channel.rs | 23 ++++++++++++++++++++--
src/client.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/messages.rs | 9 +++++++++-
src/server.rs | 16 ++++++++++++---
4 files changed, 102 insertions(+), 7 deletions(-)
@@ -25,8 +25,8 @@ use crate::{
messages::{
Broadcast, ChannelFetchTopic, ChannelFetchWhoList, ChannelInvite, ChannelJoin,
ChannelKickUser, ChannelMemberList, ChannelMessage, ChannelPart, ChannelSetMode,
ChannelUpdateTopic, FetchClientByNick, FetchUserPermission, MessageKind, ServerDisconnect,
UserKickedFromChannel, UserNickChange,
ChannelUpdateTopic, ClientAway, FetchClientByNick, FetchUserPermission, MessageKind,
ServerDisconnect, UserKickedFromChannel, UserNickChange,
},
persistence::{
events::{FetchAllUserChannelPermissions, SetUserChannelPermissions},
@@ -115,6 +115,25 @@ impl Handler<Broadcast> for Channel {
}
}
impl Handler<ClientAway> for Channel {
type Result = ();
#[instrument(parent = &msg.span, skip_all)]
fn handle(&mut self, msg: ClientAway, ctx: &mut Self::Context) -> Self::Result {
if let Some(c) = self.clients.get_mut(&msg.handle) {
c.away = msg.message;
ctx.notify(Broadcast {
message: Message {
tags: None,
prefix: Some(c.to_nick()),
command: Command::AWAY(c.away.clone()),
},
span: msg.span,
});
}
}
}
impl Handler<FetchUserPermission> for Channel {
type Result = MessageResult<FetchUserPermission>;
@@ -23,7 +23,7 @@ use crate::{
messages::{
Broadcast, ChannelFetchTopic, ChannelFetchWhoList, ChannelInvite, ChannelJoin,
ChannelKickUser, ChannelList, ChannelMemberList, ChannelMessage, ChannelPart,
ChannelSetMode, ChannelUpdateTopic, ConnectedChannels, FetchClientDetails,
ChannelSetMode, ChannelUpdateTopic, ClientAway, ConnectedChannels, FetchClientDetails,
FetchUserPermission, FetchWhoList, FetchWhois, MessageKind, PrivateMessage,
ServerAdminInfo, ServerDisconnect, ServerFetchMotd, ServerListUsers, UserKickedFromChannel,
UserNickChange, UserNickChangeInternal,
@@ -283,6 +283,50 @@ impl Handler<FetchClientDetails> for Client {
}
}
impl Handler<SetAway> for Client {
type Result = ();
#[instrument(parent = &msg.span, skip_all)]
fn handle(&mut self, msg: SetAway, ctx: &mut Self::Context) -> Self::Result {
self.connection.away = msg.msg.filter(|msg| !msg.is_empty());
let broadcast = ClientAway {
span: msg.span,
handle: ctx.address(),
message: self.connection.away.clone(),
};
self.server.do_send(broadcast.clone());
for channel in self.channels.values() {
channel.do_send(broadcast.clone());
}
let resp = if self.connection.away.is_some() {
Command::Response(
Response::RPL_NOWAWAY,
vec![
self.connection.nick.to_string(),
"You have been marked as being away".to_string(),
],
)
} else {
Command::Response(
Response::RPL_UNAWAY,
vec![
self.connection.nick.to_string(),
"You are no longer marked as being away".to_string(),
],
)
};
self.writer.write(Message {
tags: None,
prefix: None,
command: resp,
});
}
}
@@ -838,7 +882,12 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
Command::PONG(_, _) => {
self.last_active = Instant::now();
}
Command::AWAY(_) => {}
Command::AWAY(msg) => {
ctx.notify(SetAway {
span: Span::current(),
msg,
});
}
Command::REHASH => {}
Command::DIE => {}
Command::RESTART => {}
@@ -957,3 +1006,11 @@ struct JoinChannelRequest {
channels: Vec<String>,
span: Span,
}
#[derive(actix::Message, Debug)]
#[rtype(result = "()")]
struct SetAway {
msg: Option<String>,
span: Span,
}
@@ -54,6 +54,15 @@ pub struct ConnectedChannels {
pub span: Span,
}
#[derive(Message, Clone)]
#[rtype(result = "()")]
pub struct ClientAway {
pub span: Span,
pub handle: Addr<Client>,
pub message: Option<String>,
}
#[derive(Message, Clone)]
#[rtype(result = "super::server::response::ChannelList")]
@@ -25,9 +25,9 @@ use crate::{
connection::InitiatedConnection,
messages::{
Broadcast, ChannelFetchTopic, ChannelFetchWhoList, ChannelJoin, ChannelList,
ChannelMemberList, ConnectedChannels, FetchClientByNick, FetchWhoList, FetchWhois,
MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect, ServerFetchMotd,
ServerListUsers, UserConnected, UserNickChange, UserNickChangeInternal,
ChannelMemberList, ClientAway, ConnectedChannels, FetchClientByNick, FetchWhoList,
FetchWhois, MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect,
ServerFetchMotd, ServerListUsers, UserConnected, UserNickChange, UserNickChangeInternal,
},
persistence::Persistence,
server::response::{AdminInfo, ListUsers, Motd, WhoList, Whois},
@@ -215,6 +215,16 @@ impl Handler<UserNickChange> for Server {
}
}
impl Handler<ClientAway> for Server {
type Result = ();
fn handle(&mut self, msg: ClientAway, _ctx: &mut Self::Context) -> Self::Result {
if let Some(c) = self.clients.get_mut(&msg.handle) {
c.away = msg.message;
}
}
}
impl Handler<FetchClientByNick> for Server {
type Result = MessageResult<FetchClientByNick>;