🏡 index : ~doyle/titanirc.git

author Jordan Doyle <jordan@doyle.la> 2024-01-29 22:21:59.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2024-01-29 22:21:59.0 +00:00:00
commit
0a5ef8e8dca23d85c35af640c6910422fdca1149 [patch]
tree
aacc2f6b9c4647d4404039a74f297bec79accd7d
parent
253e47b477e83cc65e9d151602d695368a2d217f
download
0a5ef8e8dca23d85c35af640c6910422fdca1149.tar.gz

Reduce send-map-write duplication



Diff

 src/client.rs | 157 +++++++++++++++++++++++++++--------------------------------
 1 file changed, 74 insertions(+), 83 deletions(-)

diff --git a/src/client.rs b/src/client.rs
index f6163b6..0104b84 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1,9 +1,9 @@
use std::{collections::HashMap, time::Duration};

use actix::{
    fut::wrap_future, io::WriteHandler, Actor, ActorContext, ActorFuture, ActorFutureExt, Addr,
    AsyncContext, Context, Handler, MessageResult, ResponseActFuture, ResponseFuture, Running,
    StreamHandler, WrapFuture,
    dev::ToEnvelope, fut::wrap_future, io::WriteHandler, Actor, ActorContext, ActorFuture,
    ActorFutureExt, Addr, AsyncContext, Context, Handler, MessageResult, ResponseActFuture,
    ResponseFuture, Running, StreamHandler, WrapFuture,
};
use chrono::{DateTime, SecondsFormat, Utc};
use clap::{crate_name, crate_version};
@@ -150,6 +150,52 @@ impl Client {
                }
            })
    }

    fn channel_send_map_write<M>(
        &self,
        ctx: &mut Context<Self>,
        channel: &Addr<Channel>,
        message: M,
        map: impl FnOnce(M::Result, &Self) -> Vec<Message> + 'static,
    ) where
        M: actix::Message + Send + 'static,
        M::Result: Send,
        Channel: Handler<M>,
        <Channel as Actor>::Context: ToEnvelope<Channel, M>,
    {
        let fut = channel
            .send(message)
            .into_actor(self)
            .map(move |result, ref mut this, _ctx| {
                for message in (map)(result.unwrap(), this) {
                    this.writer.write(message);
                }
            });
        ctx.spawn(fut);
    }

    fn server_send_map_write<M>(
        &self,
        ctx: &mut Context<Self>,
        message: M,
        map: impl FnOnce(M::Result, &Self) -> Vec<Message> + 'static,
    ) where
        M: actix::Message + Send + 'static,
        M::Result: Send,
        Server: Handler<M>,
        <Server as Actor>::Context: ToEnvelope<Server, M>,
    {
        let fut =
            self.server
                .send(message)
                .into_actor(self)
                .map(move |result, ref mut this, _ctx| {
                    for message in (map)(result.unwrap(), this) {
                        this.writer.write(message);
                    }
                });
        ctx.spawn(fut);
    }
}

impl Actor for Client {
@@ -646,19 +692,12 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
                    });
                } else {
                    let span = Span::current();
                    let fut = channel
                        .send(ChannelFetchTopic { span })
                        .into_actor(self)
                        .map(|result, this, _ctx| {
                            for message in result
                                .unwrap()
                                .into_messages(this.connection.nick.to_string(), false)
                            {
                                this.writer.write(message);
                            }
                        });

                    ctx.spawn(fut);
                    self.channel_send_map_write(
                        ctx,
                        channel,
                        ChannelFetchTopic { span },
                        |res, this| res.into_messages(this.connection.nick.to_string(), false),
                    );
                }
            }
            Command::NAMES(channel_names, _) => {
@@ -678,18 +717,9 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
            }
            Command::LIST(_, _) => {
                let span = Span::current();
                let fut = self.server.send(ChannelList { span }).into_actor(self).map(
                    |result, this, _ctx| {
                        for message in result
                            .unwrap()
                            .into_messages(this.connection.nick.to_string())
                        {
                            this.writer.write(message);
                        }
                    },
                );

                ctx.spawn(fut);
                self.server_send_map_write(ctx, ChannelList { span }, |res, this| {
                    res.into_messages(this.connection.nick.to_string())
                });
            }
            Command::INVITE(nick, channel) => {
                let Some(channel) = self.channels.get(&channel) else {
@@ -747,33 +777,15 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
            }
            Command::MOTD(_) => {
                let span = Span::current();
                let fut = self
                    .server
                    .send(ServerFetchMotd { span })
                    .into_actor(self)
                    .map(|result, this, _ctx| {
                        for message in result
                            .unwrap()
                            .into_messages(this.connection.nick.to_string())
                        {
                            this.writer.write(message);
                        }
                    });

                ctx.spawn(fut);
                self.server_send_map_write(ctx, ServerFetchMotd { span }, |res, this| {
                    res.into_messages(this.connection.nick.to_string())
                });
            }
            Command::LUSERS(_, _) => {
                let span = Span::current();
                let fut = self
                    .server
                    .send(ServerListUsers { span })
                    .into_actor(self)
                    .map(|result, this, _ctx| {
                        for message in result.unwrap().into_messages(&this.connection.nick) {
                            this.writer.write(message);
                        }
                    });
                ctx.spawn(fut);
                self.server_send_map_write(ctx, ServerListUsers { span }, |res, this| {
                    res.into_messages(&this.connection.nick)
                });
            }
            Command::VERSION(_) => {
                self.writer.write(Message {
@@ -808,16 +820,9 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
            }
            Command::ADMIN(_) => {
                let span = Span::current();
                let fut = self
                    .server
                    .send(ServerAdminInfo { span })
                    .into_actor(self)
                    .map(|result, this, _ctx| {
                        for message in result.unwrap().into_messages(&this.connection.nick) {
                            this.writer.write(message);
                        }
                    });
                ctx.spawn(fut);
                self.server_send_map_write(ctx, ServerAdminInfo { span }, |res, this| {
                    res.into_messages(&this.connection.nick)
                });
            }
            Command::INFO(_) => {
                static INFO_STR: &str = include_str!("../text/info.txt");
@@ -844,31 +849,17 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
                    ),
                });
            }
            Command::WHO(Some(mask), _) => {
            Command::WHO(Some(query), _) => {
                let span = Span::current();
                let fut = self
                    .server
                    .send(FetchWhoList { span, query: mask })
                    .into_actor(self)
                    .map(|result, this, _ctx| {
                        for message in result.unwrap().into_messages(&this.connection.nick) {
                            this.writer.write(message);
                        }
                    });
                ctx.spawn(fut);
                self.server_send_map_write(ctx, FetchWhoList { span, query }, |res, this| {
                    res.into_messages(&this.connection.nick)
                });
            }
            Command::WHOIS(Some(query), _) => {
                let span = Span::current();
                let fut = self
                    .server
                    .send(FetchWhois { span, query })
                    .into_actor(self)
                    .map(|result, this, _ctx| {
                        for message in result.unwrap().into_messages(&this.connection.nick) {
                            this.writer.write(message);
                        }
                    });
                ctx.spawn(fut);
                self.server_send_map_write(ctx, FetchWhois { span, query }, |res, this| {
                    res.into_messages(&this.connection.nick)
                });
            }
            Command::WHOWAS(_, _, _) => {}
            Command::KILL(_, _) => {}