irc: rename Handler to IrcCommand and its method to handle_with

This commit is contained in:
Nikita Vilunov 2024-06-05 02:39:11 +02:00
parent 59528909c7
commit a22cde0ea8
4 changed files with 61 additions and 112 deletions

View File

@ -1,5 +1,6 @@
use std::future::Future; use std::future::Future;
use anyhow::Result;
use tokio::io::AsyncWrite; use tokio::io::AsyncWrite;
use lavina_core::player::PlayerConnection; use lavina_core::player::PlayerConnection;
@ -13,9 +14,7 @@ pub struct IrcConnection<'a, T: AsyncWrite + Unpin> {
pub player_connection: &'a mut PlayerConnection, pub player_connection: &'a mut PlayerConnection,
} }
pub trait Handler<T> /// Represents a client-to-server IRC message that can be handled by the server.
where pub trait IrcCommand {
T: AsyncWrite + Unpin, fn handle_with(&self, conn: &mut IrcConnection<impl AsyncWrite + Unpin>) -> impl Future<Output = Result<()>>;
{
fn handle(&self, arg: IrcConnection<T>) -> impl Future<Output = anyhow::Result<()>>;
} }

View File

@ -30,7 +30,7 @@ use sasl::AuthBody;
mod cap; mod cap;
use handler::Handler; use handler::{IrcCommand, IrcConnection};
mod whois; mod whois;
@ -826,15 +826,14 @@ async fn handle_incoming_message(
log::warn!("Local chans not supported"); log::warn!("Local chans not supported");
} }
}, },
ClientMessage::Whois { arg } => { ClientMessage::Whois(cmd) => {
arg.handle(handler::IrcConnection { let mut conn = IrcConnection {
server_name: config.server_name.clone(), server_name: config.server_name.clone(),
client: user.nickname.clone(), client: user.nickname.clone(),
writer, writer,
player_connection: user_handle, player_connection: user_handle,
}) };
.await?; cmd.handle_with(&mut conn).await?;
writer.flush().await?; writer.flush().await?;
} }
ClientMessage::Mode { target } => { ClientMessage::Mode { target } => {

View File

@ -1,35 +1,27 @@
use lavina_core::{ use anyhow::Result;
player::{GetInfoResult, PlayerId},
prelude::Str,
};
use proto_irc::{
client::command_args::Whois,
commands::whois::{
error::{ErrNoNicknameGiven431, ErrNoSuchNick401},
response::RplEndOfWhois318,
},
response::{IrcResponseMessage, WriteResponse},
};
use tokio::io::AsyncWrite; use tokio::io::AsyncWrite;
use crate::handler::{Handler, IrcConnection}; use crate::handler::{IrcCommand, IrcConnection};
use lavina_core::player::GetInfoResult;
use lavina_core::player::PlayerId;
use lavina_core::prelude::Str;
use proto_irc::client::Whois;
use proto_irc::commands::whois::error::{ErrNoNicknameGiven431, ErrNoSuchNick401};
use proto_irc::commands::whois::response::RplEndOfWhois318;
use proto_irc::response::IrcResponseMessage;
use proto_irc::response::WriteResponse;
impl<T: AsyncWrite + Unpin> Handler<T> for Whois { impl IrcCommand for Whois {
async fn handle(&self, body: IrcConnection<'_, T>) -> anyhow::Result<()> { async fn handle_with(&self, conn: &mut IrcConnection<'_, impl AsyncWrite + Unpin>) -> Result<()> {
match self { match self {
Whois::Nick(nick) => handle_nick_target(nick.clone(), body).await?, Whois::Nick(nick) => handle_nick_target(nick.clone(), conn).await?,
Whois::TargetNick(_, nick) => handle_nick_target(nick.clone(), body).await?, Whois::TargetNick(_, nick) => handle_nick_target(nick.clone(), conn).await?,
Whois::EmptyArgs => { Whois::EmptyArgs => {
let IrcConnection {
server_name,
mut writer,
..
} = body;
IrcResponseMessage::empty_tags( IrcResponseMessage::empty_tags(
Some(server_name.clone()), Some(conn.server_name.clone()),
ErrNoNicknameGiven431::new(server_name.clone()), ErrNoNicknameGiven431::new(conn.server_name.clone()),
) )
.write_response(&mut writer) .write_response(conn.writer)
.await? .await?
} }
} }
@ -37,31 +29,23 @@ impl<T: AsyncWrite + Unpin> Handler<T> for Whois {
} }
} }
async fn handle_nick_target(nick: Str, body: IrcConnection<'_, impl AsyncWrite + Unpin>) -> anyhow::Result<()> { async fn handle_nick_target(nick: Str, conn: &mut IrcConnection<'_, impl AsyncWrite + Unpin>) -> Result<()> {
let IrcConnection { match conn.player_connection.check_user_existence(PlayerId::from(nick.clone())?).await? {
server_name, GetInfoResult::UserExists => {}
mut writer, GetInfoResult::UserDoesntExist => {
client, IrcResponseMessage::empty_tags(
player_connection, Some(conn.server_name.clone()),
} = body; ErrNoSuchNick401::new(conn.client.clone(), nick.clone()),
)
if let GetInfoResult::UserDoesntExist = .write_response(conn.writer)
player_connection.check_user_existence(PlayerId::from(nick.clone())?).await? .await?
{ }
IrcResponseMessage::empty_tags(
Some(server_name.clone()),
ErrNoSuchNick401::new(client.clone(), nick.clone()),
)
.write_response(&mut writer)
.await?
} }
IrcResponseMessage::empty_tags( IrcResponseMessage::empty_tags(
Some(server_name.clone()), Some(conn.server_name.clone()),
RplEndOfWhois318::new(client.clone(), nick.clone()), RplEndOfWhois318::new(conn.client.clone(), nick.clone()),
) )
.write_response(&mut writer) .write_response(conn.writer)
.await?; .await?;
Ok(()) Ok(())
} }

View File

@ -43,9 +43,7 @@ pub enum ClientMessage {
target: Recipient, // aka mask target: Recipient, // aka mask
}, },
/// WHOIS [<target>] <nick> /// WHOIS [<target>] <nick>
Whois { Whois(Whois),
arg: command_args::Whois,
},
/// `TOPIC <chan> :<topic>` /// `TOPIC <chan> :<topic>`
Topic { Topic {
chan: Chan, chan: Chan,
@ -71,15 +69,11 @@ pub enum ClientMessage {
}, },
} }
pub mod command_args { #[derive(Clone, Debug, PartialEq, Eq)]
use crate::prelude::Str; pub enum Whois {
Nick(Str),
#[derive(Clone, Debug, PartialEq, Eq)] TargetNick(Str, Str),
pub enum Whois { EmptyArgs,
Nick(Str),
TargetNick(Str, Str),
EmptyArgs,
}
} }
pub fn client_message(input: &str) -> Result<ClientMessage> { pub fn client_message(input: &str) -> Result<ClientMessage> {
@ -204,24 +198,9 @@ fn client_message_whois(input: &str) -> IResult<&str, ClientMessage> {
let (input, _) = tag("WHOIS ")(input)?; let (input, _) = tag("WHOIS ")(input)?;
let args: Vec<_> = input.split_whitespace().collect(); let args: Vec<_> = input.split_whitespace().collect();
match args.as_slice()[..] { match args.as_slice()[..] {
[nick] => Ok(( [nick] => Ok(("", ClientMessage::Whois(Whois::Nick(nick.into())))),
"", [target, nick, ..] => Ok(("", ClientMessage::Whois(Whois::TargetNick(target.into(), nick.into())))),
ClientMessage::Whois { [] => Ok(("", ClientMessage::Whois(Whois::EmptyArgs))),
arg: command_args::Whois::Nick(nick.into()),
},
)),
[target, nick, ..] => Ok((
"",
ClientMessage::Whois {
arg: command_args::Whois::TargetNick(target.into(), nick.into()),
},
)),
[] => Ok((
"",
ClientMessage::Whois {
arg: command_args::Whois::EmptyArgs,
},
)),
} }
} }
@ -448,35 +427,23 @@ mod test {
let res_more_than_two_params = client_message(test_more_than_two_params); let res_more_than_two_params = client_message(test_more_than_two_params);
let res_none_none_params = client_message(test_none_none_params); let res_none_none_params = client_message(test_none_none_params);
let expected_arg = ClientMessage::Whois { let expected_arg = ClientMessage::Whois(Whois::Nick("val".into()));
arg: command_args::Whois::Nick("val".into()), let expected_user_user = ClientMessage::Whois(Whois::TargetNick("val".into(), "val".into()));
};
let expected_user_user = ClientMessage::Whois {
arg: command_args::Whois::TargetNick("val".into(), "val".into()),
};
let expected_server_user = ClientMessage::Whois { let expected_server_user = ClientMessage::Whois(Whois::TargetNick("com.test.server".into(), "user".into()));
arg: command_args::Whois::TargetNick("com.test.server".into(), "user".into()),
};
let expected_user_server = ClientMessage::Whois { let expected_user_server = ClientMessage::Whois(Whois::TargetNick("user".into(), "com.test.server".into()));
arg: command_args::Whois::TargetNick("user".into(), "com.test.server".into()),
};
let expected_user_list = ClientMessage::Whois { let expected_user_list = ClientMessage::Whois(Whois::Nick("user_1,user_2,user_3".into()));
arg: command_args::Whois::Nick("user_1,user_2,user_3".into()), let expected_server_user_list = ClientMessage::Whois(Whois::TargetNick(
}; "com.test.server".into(),
let expected_server_user_list = ClientMessage::Whois { "user_1,user_2,user_3".into(),
arg: command_args::Whois::TargetNick("com.test.server".into(), "user_1,user_2,user_3".into()), ));
};
let expected_more_than_two_params = ClientMessage::Whois { let expected_more_than_two_params =
arg: command_args::Whois::TargetNick("test.server".into(), "user_1,user_2,user_3".into()), ClientMessage::Whois(Whois::TargetNick("test.server".into(), "user_1,user_2,user_3".into()));
};
let expected_none_none_params = ClientMessage::Whois { let expected_none_none_params = ClientMessage::Whois(Whois::EmptyArgs);
arg: command_args::Whois::EmptyArgs,
};
assert_matches!(res_one_arg, Ok(result) => assert_eq!(expected_arg, result)); assert_matches!(res_one_arg, Ok(result) => assert_eq!(expected_arg, result));
assert_matches!(res_user_user, Ok(result) => assert_eq!(expected_user_user, result)); assert_matches!(res_user_user, Ok(result) => assert_eq!(expected_user_user, result));