forked from lavina/lavina
irc: rename Handler to IrcCommand and its method to handle_with
This commit is contained in:
parent
59528909c7
commit
a22cde0ea8
|
@ -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<()>>;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 } => {
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Reference in New Issue