From 87367644cc243bd318fbe008adc41cbb78d4d35b Mon Sep 17 00:00:00 2001 From: rasul Date: Sat, 4 Apr 2020 10:12:35 -0500 Subject: [PATCH] Subcommand for working with room descriptions Create the CommandSetRoomDescription sub command, move the former description command into it and rename it set, and the delete command. --- src/command/set/room/description/delete.rs | 42 +++++++++++++++++++ .../set/room/description/description.rs | 39 +++++++++++++++++ src/command/set/room/description/mod.rs | 7 ++++ .../{description.rs => description/set.rs} | 10 ++--- src/command/set/room/room.rs | 26 ++++++++++-- 5 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 src/command/set/room/description/delete.rs create mode 100644 src/command/set/room/description/description.rs create mode 100644 src/command/set/room/description/mod.rs rename src/command/set/room/{description.rs => description/set.rs} (86%) diff --git a/src/command/set/room/description/delete.rs b/src/command/set/room/description/delete.rs new file mode 100644 index 0000000..5ddbd80 --- /dev/null +++ b/src/command/set/room/description/delete.rs @@ -0,0 +1,42 @@ +use std::str::FromStr; + +use mio::Token; + +use crate::command::CommandSetRoomDescription; +use crate::database::Db; +use crate::queue::SendQueue; +use crate::{try_option_send_error, try_send, try_send_error}; + +impl CommandSetRoomDescription { + /// Set the specified line in the description to the specified text. + pub fn dispatch_delete(&self, args: String, token: Token, db: &mut Db) -> SendQueue { + // make sure something was provided + if args.is_empty() { + return SendQueue(vec![(token, "Delete which line?".into(), true)].into()); + } + + // try and get the line number + let line_num: usize = try_send!( + token, + u8::from_str(&args), + "Can't figure out line number from '{}'.", + &args + ) + .into(); + + // load the player and room + let player = try_option_send_error!(token, db.get_connected_player(token)); + let mut room = try_option_send_error!(token, db.load_room(player.location)); + + // make sure description has enough lines + if line_num > room.description.len().into() || line_num <= 0 { + return SendQueue(vec![(token, "Line doeesn't exist".into(), true)].into()); + } + + // remove the line and save + room.description.remove(line_num-1); + let _ = try_send_error!(token, db.save_room(&room)); + + SendQueue::ok(token) + } +} diff --git a/src/command/set/room/description/description.rs b/src/command/set/room/description/description.rs new file mode 100644 index 0000000..2af9a0b --- /dev/null +++ b/src/command/set/room/description/description.rs @@ -0,0 +1,39 @@ +use std::default::Default; + +use mio::Token; +use strum_macros::{Display, EnumIter}; + +use crate::command::Parse; +use crate::database::Db; +use crate::queue::SendQueue; + +#[derive(Clone, Debug, Display, EnumIter, Eq, Ord, PartialEq, PartialOrd)] +pub enum CommandSetRoomDescription { + Delete, + Set, + Default, +} + +impl Default for CommandSetRoomDescription { + fn default() -> Self { + Self::Default + } +} + +impl Parse for CommandSetRoomDescription { + fn help(&self) -> &str { + match self { + Self::Delete => "set room description delete LINE :: Delete line LINE from room description", + Self::Set => "set room description set LINE DESC :: Set room description line LINE to DESC", + Self::Default => "", + } + } + + fn dispatch_map(&self) -> fn(&Self, String, Token, &mut Db) -> SendQueue { + match self { + Self::Delete => Self::dispatch_delete, + Self::Set => Self::dispatch_set, + Self::Default => Self::dispatch_default, + } + } +} diff --git a/src/command/set/room/description/mod.rs b/src/command/set/room/description/mod.rs new file mode 100644 index 0000000..d06db6d --- /dev/null +++ b/src/command/set/room/description/mod.rs @@ -0,0 +1,7 @@ +mod delete; +mod description; +mod set; + +pub use delete::*; +pub use description::*; +pub use set::*; diff --git a/src/command/set/room/description.rs b/src/command/set/room/description/set.rs similarity index 86% rename from src/command/set/room/description.rs rename to src/command/set/room/description/set.rs index 59827b2..48cd6aa 100644 --- a/src/command/set/room/description.rs +++ b/src/command/set/room/description/set.rs @@ -2,23 +2,23 @@ use std::str::FromStr; use mio::Token; -use crate::command::CommandSetRoom; +use crate::command::CommandSetRoomDescription; use crate::database::Db; use crate::queue::SendQueue; use crate::{option_send, try_option_send_error, try_send, try_send_error}; -impl CommandSetRoom { +impl CommandSetRoomDescription { /// Set the specified line in the description to the specified text. - pub fn dispatch_description(&self, args: String, token: Token, db: &mut Db) -> SendQueue { - // parse the arguments + pub fn dispatch_set(&self, args: String, token: Token, db: &mut Db) -> SendQueue { + // make sure something was provided if args.is_empty() { return SendQueue( vec![(token, "Set what line to what description?".into(), true)].into(), ); } + // parse the arguments let space = option_send!(token, args.find(' '), "Set what line to what description?"); - let mut line_string = args.clone(); let mut description = line_string.split_off(space); description.remove(0); diff --git a/src/command/set/room/room.rs b/src/command/set/room/room.rs index eb547cb..46a0860 100644 --- a/src/command/set/room/room.rs +++ b/src/command/set/room/room.rs @@ -3,13 +3,13 @@ use std::default::Default; use mio::Token; use strum_macros::{Display, EnumIter}; -use crate::command::Parse; +use crate::command::{CommandSetRoomDescription, Parse, ParserError}; use crate::database::Db; use crate::queue::SendQueue; #[derive(Clone, Debug, Display, EnumIter, Eq, Ord, PartialEq, PartialOrd)] pub enum CommandSetRoom { - Description, + Description(CommandSetRoomDescription), Name, Default, } @@ -23,15 +23,33 @@ impl Default for CommandSetRoom { impl Parse for CommandSetRoom { fn help(&self) -> &str { match self { - Self::Description => "set room description LINE DESCRIPTION :: Set line LINE of description to DESCRIPTION.", + Self::Description(_) => "", Self::Name => "set room name NEW_NAME :: Set room name to NEW_NAME.", Self::Default => "", } } + fn parse_subcommand(&self, s: String) -> Result<(Self, String), ParserError> { + match self { + Self::Description(_) => { + let (command, args) = CommandSetRoomDescription::parse(s)?; + Ok((Self::Description(command), args)) + }, + Self::Default => Err(ParserError::Default), + _ => Ok((self.clone(), s)), + } + } + + fn dispatch_map_subcommand(&self, args: String, token: Token, db: &mut Db) -> SendQueue { + match self { + Self::Description(command) => command.dispatch(command, args, token, db), + _ => SendQueue::new(), + } + } + fn dispatch_map(&self) -> fn(&Self, String, Token, &mut Db) -> SendQueue { match self { - Self::Description => Self::dispatch_description, + Self::Description(_) => Self::dispatch_map_subcommand, Self::Name => Self::dispatch_name, Self::Default => Self::dispatch_default, }