blastmud/blastmud_game/src/message_handler/user_commands.rs

81 lines
2.3 KiB
Rust
Raw Normal View History

2022-12-24 21:16:23 +11:00
use super::ListenerSession;
2022-12-24 13:43:28 +11:00
use crate::DResult;
2022-12-25 00:25:52 +11:00
use crate::db::{DBTrans, DBPool};
2022-12-24 13:43:28 +11:00
use ansi_macro::ansi;
2022-12-24 21:16:23 +11:00
use phf::phf_map;
use async_trait::async_trait;
use crate::models::session::Session;
2022-12-24 13:43:28 +11:00
2022-12-24 21:16:23 +11:00
mod parsing;
mod ignore;
mod help;
pub struct VerbContext<'l> {
session: &'l ListenerSession,
session_dat: &'l mut Session,
2022-12-25 00:25:52 +11:00
trans: &'l DBTrans
2022-12-24 21:16:23 +11:00
}
pub enum CommandHandlingError {
UserError(String),
SystemError(Box<dyn std::error::Error + Send + Sync>)
}
use CommandHandlingError::*;
#[async_trait]
pub trait UserVerb {
async fn handle(self: &Self, ctx: &VerbContext, verb: &str, remaining: &str) -> UResult<()>;
}
pub type UserVerbRef = &'static (dyn UserVerb + Sync + Send);
pub type UResult<A> = Result<A, CommandHandlingError>;
impl From<Box<dyn std::error::Error + Send + Sync>> for CommandHandlingError {
fn from(input: Box<dyn std::error::Error + Send + Sync>) -> CommandHandlingError {
SystemError(input)
}
}
pub fn user_error<A>(msg: String) -> UResult<A> {
Err(UserError(msg))
}
type UserVerbRegistry = phf::Map<&'static str, UserVerbRef>;
static ALWAYS_AVAILABLE_COMMANDS: UserVerbRegistry = phf_map! {
"" => ignore::VERB,
"help" => help::VERB
};
pub async fn handle(session: &ListenerSession, msg: &str, pool: &DBPool) -> DResult<()> {
let (cmd, params) = parsing::parse_command_name(msg);
2022-12-25 00:25:52 +11:00
let trans = pool.start_transaction().await?;
let mut session_dat = match trans.get_session_model(session).await? {
None => { return Ok(()) }
Some(v) => v
};
2022-12-24 21:16:23 +11:00
let handler_opt = ALWAYS_AVAILABLE_COMMANDS.get(cmd);
let ctx = VerbContext { session, trans: &trans, session_dat: &mut session_dat };
2022-12-24 21:16:23 +11:00
match handler_opt {
None => {
2022-12-25 00:25:52 +11:00
trans.queue_for_session(session,
ansi!(
"That's not a command I know. Try <bold>help<reset>\r\n"
)
2022-12-24 21:16:23 +11:00
).await?;
}
Some(handler) => {
match handler.handle(&ctx, cmd, params).await {
2022-12-24 21:16:23 +11:00
Ok(()) => {}
Err(UserError(err_msg)) => {
2022-12-25 00:25:52 +11:00
trans.queue_for_session(session, &(err_msg + "\r\n")).await?;
2022-12-24 21:16:23 +11:00
}
Err(SystemError(e)) => Err(e)?
}
}
}
2022-12-25 00:25:52 +11:00
trans.commit().await?;
2022-12-24 13:43:28 +11:00
Ok(())
}