diff --git a/pumpkin-protocol/src/client/play/c_command_suggestions.rs b/pumpkin-protocol/src/client/play/c_command_suggestions.rs index 25ae6683..c137b9ad 100644 --- a/pumpkin-protocol/src/client/play/c_command_suggestions.rs +++ b/pumpkin-protocol/src/client/play/c_command_suggestions.rs @@ -35,7 +35,7 @@ impl ClientPacket for CCommandSuggestions<'_> { bytebuf.put_var_int(&self.length); bytebuf.put_list(&self.matches, |bytebuf, suggestion| { - bytebuf.put_string(suggestion.suggestion); + bytebuf.put_string(&suggestion.suggestion); bytebuf.put_bool(suggestion.tooltip.is_some()); if let Some(tooltip) = &suggestion.tooltip { bytebuf.put_slice(&tooltip.encode()); @@ -46,12 +46,12 @@ impl ClientPacket for CCommandSuggestions<'_> { #[derive(PartialEq, Eq, Hash, Debug)] pub struct CommandSuggestion<'a> { - pub suggestion: &'a str, + pub suggestion: String, pub tooltip: Option>, } impl<'a> CommandSuggestion<'a> { - pub fn new(suggestion: &'a str, tooltip: Option>) -> Self { + pub fn new(suggestion: String, tooltip: Option>) -> Self { Self { suggestion, tooltip, diff --git a/pumpkin/src/command/args/arg_block.rs b/pumpkin/src/command/args/arg_block.rs index fe11228f..77962552 100644 --- a/pumpkin/src/command/args/arg_block.rs +++ b/pumpkin/src/command/args/arg_block.rs @@ -31,7 +31,7 @@ impl GetClientSideArgParser for BlockArgumentConsumer { #[async_trait] impl ArgumentConsumer for BlockArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -41,7 +41,7 @@ impl ArgumentConsumer for BlockArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -51,19 +51,15 @@ impl ArgumentConsumer for BlockArgumentConsumer { } impl DefaultNameArgConsumer for BlockArgumentConsumer { - fn default_name(&self) -> &'static str { - "block" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - self + fn default_name(&self) -> String { + "block".to_string() } } impl<'a> FindArg<'a> for BlockArgumentConsumer { type Data = &'a Block; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Block(name)) => block_registry::get_block(name).map_or_else( || { diff --git a/pumpkin/src/command/args/arg_bool.rs b/pumpkin/src/command/args/arg_bool.rs index fc47f590..39b69c89 100644 --- a/pumpkin/src/command/args/arg_bool.rs +++ b/pumpkin/src/command/args/arg_bool.rs @@ -23,7 +23,7 @@ impl GetClientSideArgParser for BoolArgConsumer { #[async_trait] impl ArgumentConsumer for BoolArgConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -38,7 +38,7 @@ impl ArgumentConsumer for BoolArgConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -50,7 +50,7 @@ impl ArgumentConsumer for BoolArgConsumer { impl<'a> FindArg<'a> for BoolArgConsumer { type Data = bool; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Bool(data)) => Ok(*data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_bossbar_color.rs b/pumpkin/src/command/args/arg_bossbar_color.rs index 94df5a4c..664264ea 100644 --- a/pumpkin/src/command/args/arg_bossbar_color.rs +++ b/pumpkin/src/command/args/arg_bossbar_color.rs @@ -27,7 +27,7 @@ impl GetClientSideArgParser for BossbarColorArgumentConsumer { #[async_trait] impl ArgumentConsumer for BossbarColorArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -49,7 +49,7 @@ impl ArgumentConsumer for BossbarColorArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -57,26 +57,22 @@ impl ArgumentConsumer for BossbarColorArgumentConsumer { let colors = ["blue", "green", "pink", "purple", "red", "white", "yellow"]; let suggestions: Vec = colors .iter() - .map(|color| CommandSuggestion::new(color, None)) + .map(|color| CommandSuggestion::new((*color).to_string(), None)) .collect(); Ok(Some(suggestions)) } } impl DefaultNameArgConsumer for BossbarColorArgumentConsumer { - fn default_name(&self) -> &'static str { - "color" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - self + fn default_name(&self) -> String { + "color".to_string() } } impl<'a> FindArg<'a> for BossbarColorArgumentConsumer { type Data = &'a BossbarColor; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::BossbarColor(data)) => Ok(data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_bossbar_style.rs b/pumpkin/src/command/args/arg_bossbar_style.rs index 6111688b..6d3b2d44 100644 --- a/pumpkin/src/command/args/arg_bossbar_style.rs +++ b/pumpkin/src/command/args/arg_bossbar_style.rs @@ -27,7 +27,7 @@ impl GetClientSideArgParser for BossbarStyleArgumentConsumer { #[async_trait] impl ArgumentConsumer for BossbarStyleArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -47,7 +47,7 @@ impl ArgumentConsumer for BossbarStyleArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -61,26 +61,22 @@ impl ArgumentConsumer for BossbarStyleArgumentConsumer { ]; let suggestions: Vec = styles .iter() - .map(|style| CommandSuggestion::new(style, None)) + .map(|style| CommandSuggestion::new((*style).to_string(), None)) .collect(); Ok(Some(suggestions)) } } impl DefaultNameArgConsumer for BossbarStyleArgumentConsumer { - fn default_name(&self) -> &'static str { - "style" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - self + fn default_name(&self) -> String { + "style".to_string() } } impl<'a> FindArg<'a> for BossbarStyleArgumentConsumer { type Data = &'a BossbarDivisions; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::BossbarStyle(data)) => Ok(data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_bounded_num.rs b/pumpkin/src/command/args/arg_bounded_num.rs index 41410367..0cd20af2 100644 --- a/pumpkin/src/command/args/arg_bounded_num.rs +++ b/pumpkin/src/command/args/arg_bounded_num.rs @@ -25,7 +25,7 @@ where Self: GetClientSideArgParser, { async fn consume<'a>( - &self, + &'a self, _src: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -48,7 +48,7 @@ where } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -238,12 +238,8 @@ impl DefaultNameArgConsumer for BoundedNumArgumentConsumer where Self: ArgumentConsumer, { - fn default_name(&self) -> &'static str { + fn default_name(&self) -> String { // setting a single default name for all BoundedNumArgumentConsumer variants is probably a bad idea since it would lead to confusion - self.name.expect("Only use *_default variants of methods with a BoundedNumArgumentConsumer that has a name.") - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - self + self.name.expect("Only use *_default variants of methods with a BoundedNumArgumentConsumer that has a name.").to_string() } } diff --git a/pumpkin/src/command/args/arg_command.rs b/pumpkin/src/command/args/arg_command.rs index 9055fde1..a8ea8234 100644 --- a/pumpkin/src/command/args/arg_command.rs +++ b/pumpkin/src/command/args/arg_command.rs @@ -30,7 +30,7 @@ impl GetClientSideArgParser for CommandTreeArgumentConsumer { #[async_trait] impl ArgumentConsumer for CommandTreeArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, server: &'a Server, args: &mut RawArgs<'a>, @@ -40,11 +40,11 @@ impl ArgumentConsumer for CommandTreeArgumentConsumer { let dispatcher = server.command_dispatcher.read().await; dispatcher .get_tree(s) - .map_or_else(|_| None, |tree| Some(Arg::CommandTree(tree))) + .map_or_else(|_| None, |tree| Some(Arg::CommandTree(tree.clone()))) } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, server: &'a Server, input: &'a str, @@ -58,26 +58,22 @@ impl ArgumentConsumer for CommandTreeArgumentConsumer { .commands .keys() .filter(|suggestion| suggestion.starts_with(input)) - .map(|suggestion| CommandSuggestion::new(suggestion, None)) + .map(|suggestion| CommandSuggestion::new(suggestion.to_string(), None)) .collect(); Ok(Some(suggestions)) } } impl DefaultNameArgConsumer for CommandTreeArgumentConsumer { - fn default_name(&self) -> &'static str { - "cmd" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "cmd".to_string() } } impl<'a> FindArg<'a> for CommandTreeArgumentConsumer { - type Data = &'a CommandTree<'a>; + type Data = &'a CommandTree; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::CommandTree(tree)) => Ok(tree), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_entities.rs b/pumpkin/src/command/args/arg_entities.rs index 102a177b..0c202ac7 100644 --- a/pumpkin/src/command/args/arg_entities.rs +++ b/pumpkin/src/command/args/arg_entities.rs @@ -34,7 +34,7 @@ impl GetClientSideArgParser for EntitiesArgumentConsumer { #[async_trait] impl ArgumentConsumer for EntitiesArgumentConsumer { async fn consume<'a>( - &self, + &'a self, src: &CommandSender<'a>, server: &'a Server, args: &mut RawArgs<'a>, @@ -47,7 +47,7 @@ impl ArgumentConsumer for EntitiesArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -57,19 +57,15 @@ impl ArgumentConsumer for EntitiesArgumentConsumer { } impl DefaultNameArgConsumer for EntitiesArgumentConsumer { - fn default_name(&self) -> &'static str { - "targets" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "targets".to_string() } } impl<'a> FindArg<'a> for EntitiesArgumentConsumer { type Data = &'a [Arc]; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Entities(data)) => Ok(data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_entity.rs b/pumpkin/src/command/args/arg_entity.rs index 37e4dac0..bbbed190 100644 --- a/pumpkin/src/command/args/arg_entity.rs +++ b/pumpkin/src/command/args/arg_entity.rs @@ -37,7 +37,7 @@ impl GetClientSideArgParser for EntityArgumentConsumer { #[async_trait] impl ArgumentConsumer for EntityArgumentConsumer { async fn consume<'a>( - &self, + &'a self, src: &CommandSender<'a>, server: &'a Server, args: &mut RawArgs<'a>, @@ -69,7 +69,7 @@ impl ArgumentConsumer for EntityArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -79,19 +79,15 @@ impl ArgumentConsumer for EntityArgumentConsumer { } impl DefaultNameArgConsumer for EntityArgumentConsumer { - fn default_name(&self) -> &'static str { - "target" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "target".to_string() } } impl<'a> FindArg<'a> for EntityArgumentConsumer { type Data = Arc; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Entity(data)) => Ok(data.clone()), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_gamemode.rs b/pumpkin/src/command/args/arg_gamemode.rs index d520b25c..fee1264d 100644 --- a/pumpkin/src/command/args/arg_gamemode.rs +++ b/pumpkin/src/command/args/arg_gamemode.rs @@ -29,7 +29,7 @@ impl GetClientSideArgParser for GamemodeArgumentConsumer { #[async_trait] impl ArgumentConsumer for GamemodeArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -50,7 +50,7 @@ impl ArgumentConsumer for GamemodeArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -60,19 +60,15 @@ impl ArgumentConsumer for GamemodeArgumentConsumer { } impl DefaultNameArgConsumer for GamemodeArgumentConsumer { - fn default_name(&self) -> &'static str { - "gamemode" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "gamemode".to_string() } } impl<'a> FindArg<'a> for GamemodeArgumentConsumer { type Data = GameMode; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::GameMode(data)) => Ok(*data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_item.rs b/pumpkin/src/command/args/arg_item.rs index 481feb7d..bf4254b9 100644 --- a/pumpkin/src/command/args/arg_item.rs +++ b/pumpkin/src/command/args/arg_item.rs @@ -29,7 +29,7 @@ impl GetClientSideArgParser for ItemArgumentConsumer { #[async_trait] impl ArgumentConsumer for ItemArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -39,7 +39,7 @@ impl ArgumentConsumer for ItemArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -49,19 +49,15 @@ impl ArgumentConsumer for ItemArgumentConsumer { } impl DefaultNameArgConsumer for ItemArgumentConsumer { - fn default_name(&self) -> &'static str { - "item" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - self + fn default_name(&self) -> String { + "item".to_string() } } impl<'a> FindArg<'a> for ItemArgumentConsumer { type Data = (&'a str, &'a Item); - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Item(name)) => item_registry::get_item(name).map_or_else( || { diff --git a/pumpkin/src/command/args/arg_message.rs b/pumpkin/src/command/args/arg_message.rs index 00af2d87..8d4081d6 100644 --- a/pumpkin/src/command/args/arg_message.rs +++ b/pumpkin/src/command/args/arg_message.rs @@ -29,7 +29,7 @@ impl GetClientSideArgParser for MsgArgConsumer { #[async_trait] impl ArgumentConsumer for MsgArgConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -45,7 +45,7 @@ impl ArgumentConsumer for MsgArgConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -55,19 +55,15 @@ impl ArgumentConsumer for MsgArgConsumer { } impl DefaultNameArgConsumer for MsgArgConsumer { - fn default_name(&self) -> &'static str { - "msg" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "msg".to_string() } } impl<'a> FindArg<'a> for MsgArgConsumer { type Data = &'a str; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Msg(data)) => Ok(data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_players.rs b/pumpkin/src/command/args/arg_players.rs index 0e8876a7..c7fdc70a 100644 --- a/pumpkin/src/command/args/arg_players.rs +++ b/pumpkin/src/command/args/arg_players.rs @@ -33,7 +33,7 @@ impl GetClientSideArgParser for PlayersArgumentConsumer { #[async_trait] impl ArgumentConsumer for PlayersArgumentConsumer { async fn consume<'a>( - &self, + &'a self, src: &CommandSender<'a>, server: &'a Server, args: &mut RawArgs<'a>, @@ -63,7 +63,7 @@ impl ArgumentConsumer for PlayersArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -73,19 +73,15 @@ impl ArgumentConsumer for PlayersArgumentConsumer { } impl DefaultNameArgConsumer for PlayersArgumentConsumer { - fn default_name(&self) -> &'static str { - "player" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "player".to_string() } } impl<'a> FindArg<'a> for PlayersArgumentConsumer { type Data = &'a [Arc]; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Players(data)) => Ok(data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_position_2d.rs b/pumpkin/src/command/args/arg_position_2d.rs index 107ea432..9a9c5b56 100644 --- a/pumpkin/src/command/args/arg_position_2d.rs +++ b/pumpkin/src/command/args/arg_position_2d.rs @@ -32,7 +32,7 @@ impl GetClientSideArgParser for Position2DArgumentConsumer { #[async_trait] impl ArgumentConsumer for Position2DArgumentConsumer { async fn consume<'a>( - &self, + &'a self, src: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -45,7 +45,7 @@ impl ArgumentConsumer for Position2DArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -73,19 +73,15 @@ impl MaybeRelativePosition2D { } impl DefaultNameArgConsumer for Position2DArgumentConsumer { - fn default_name(&self) -> &'static str { - "pos2d" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "pos2d".to_string() } } impl<'a> FindArg<'a> for Position2DArgumentConsumer { type Data = Vector2; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Pos2D(data)) => Ok(*data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_position_3d.rs b/pumpkin/src/command/args/arg_position_3d.rs index 1e58ad81..8df9761c 100644 --- a/pumpkin/src/command/args/arg_position_3d.rs +++ b/pumpkin/src/command/args/arg_position_3d.rs @@ -29,7 +29,7 @@ impl GetClientSideArgParser for Position3DArgumentConsumer { #[async_trait] impl ArgumentConsumer for Position3DArgumentConsumer { async fn consume<'a>( - &self, + &'a self, src: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -42,7 +42,7 @@ impl ArgumentConsumer for Position3DArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -76,19 +76,15 @@ impl MaybeRelativePosition3D { } impl DefaultNameArgConsumer for Position3DArgumentConsumer { - fn default_name(&self) -> &'static str { - "pos" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "pos".to_string() } } impl<'a> FindArg<'a> for Position3DArgumentConsumer { type Data = Vector3; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Pos3D(data)) => Ok(*data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_position_block.rs b/pumpkin/src/command/args/arg_position_block.rs index 861eec12..4f5b3a40 100644 --- a/pumpkin/src/command/args/arg_position_block.rs +++ b/pumpkin/src/command/args/arg_position_block.rs @@ -30,7 +30,7 @@ impl GetClientSideArgParser for BlockPosArgumentConsumer { #[async_trait] impl ArgumentConsumer for BlockPosArgumentConsumer { async fn consume<'a>( - &self, + &'a self, src: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -43,7 +43,7 @@ impl ArgumentConsumer for BlockPosArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -77,19 +77,15 @@ impl MaybeRelativeBlockPos { } impl DefaultNameArgConsumer for BlockPosArgumentConsumer { - fn default_name(&self) -> &'static str { - "block_pos" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "block_pos".to_string() } } impl<'a> FindArg<'a> for BlockPosArgumentConsumer { type Data = WorldPosition; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::BlockPos(data)) => Ok(*data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_resource_location.rs b/pumpkin/src/command/args/arg_resource_location.rs index 02781593..c156a57f 100644 --- a/pumpkin/src/command/args/arg_resource_location.rs +++ b/pumpkin/src/command/args/arg_resource_location.rs @@ -27,7 +27,7 @@ impl GetClientSideArgParser for ResourceLocationArgumentConsumer { #[async_trait] impl ArgumentConsumer for ResourceLocationArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -36,7 +36,7 @@ impl ArgumentConsumer for ResourceLocationArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -60,19 +60,15 @@ impl ArgumentConsumer for ResourceLocationArgumentConsumer { } impl DefaultNameArgConsumer for ResourceLocationArgumentConsumer { - fn default_name(&self) -> &'static str { - "id" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - self + fn default_name(&self) -> String { + "id".to_string() } } impl<'a> FindArg<'a> for ResourceLocationArgumentConsumer { type Data = &'a str; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::ResourceLocation(data)) => Ok(data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_rotation.rs b/pumpkin/src/command/args/arg_rotation.rs index 6e53f2f9..91b3363b 100644 --- a/pumpkin/src/command/args/arg_rotation.rs +++ b/pumpkin/src/command/args/arg_rotation.rs @@ -27,7 +27,7 @@ impl GetClientSideArgParser for RotationArgumentConsumer { #[async_trait] impl ArgumentConsumer for RotationArgumentConsumer { async fn consume<'a>( - &self, + &'a self, _src: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -51,7 +51,7 @@ impl ArgumentConsumer for RotationArgumentConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -61,19 +61,15 @@ impl ArgumentConsumer for RotationArgumentConsumer { } impl DefaultNameArgConsumer for RotationArgumentConsumer { - fn default_name(&self) -> &'static str { - "rotation" - } - - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer { - &Self + fn default_name(&self) -> String { + "rotation".to_string() } } impl<'a> FindArg<'a> for RotationArgumentConsumer { type Data = (f32, f32); - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Rotation(yaw, pitch)) => Ok((*yaw, *pitch)), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/arg_simple.rs b/pumpkin/src/command/args/arg_simple.rs index 1412d63e..67207fb8 100644 --- a/pumpkin/src/command/args/arg_simple.rs +++ b/pumpkin/src/command/args/arg_simple.rs @@ -30,7 +30,7 @@ impl GetClientSideArgParser for SimpleArgConsumer { #[async_trait] impl ArgumentConsumer for SimpleArgConsumer { async fn consume<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, args: &mut RawArgs<'a>, @@ -39,7 +39,7 @@ impl ArgumentConsumer for SimpleArgConsumer { } async fn suggest<'a>( - &self, + &'a self, _sender: &CommandSender<'a>, _server: &'a Server, _input: &'a str, @@ -51,7 +51,7 @@ impl ArgumentConsumer for SimpleArgConsumer { impl<'a> FindArg<'a> for SimpleArgConsumer { type Data = &'a str; - fn find_arg(args: &'a super::ConsumedArgs, name: &'a str) -> Result { + fn find_arg(args: &'a super::ConsumedArgs, name: &str) -> Result { match args.get(name) { Some(Arg::Simple(data)) => Ok(data), _ => Err(CommandError::InvalidConsumption(Some(name.to_string()))), diff --git a/pumpkin/src/command/args/mod.rs b/pumpkin/src/command/args/mod.rs index 8342386b..f1fa8f85 100644 --- a/pumpkin/src/command/args/mod.rs +++ b/pumpkin/src/command/args/mod.rs @@ -42,21 +42,21 @@ mod coordinate; #[async_trait] pub(crate) trait ArgumentConsumer: Sync + GetClientSideArgParser { async fn consume<'a>( - &self, + &'a self, sender: &CommandSender<'a>, server: &'a Server, args: &mut RawArgs<'a>, - ) -> Option>; + ) -> Option; /// Used for tab completion (but only if argument suggestion type is "minecraft:ask_server"!). /// /// NOTE: This is called after this consumer's [`ArgumentConsumer::consume`] method returned None, so if args is used here, make sure [`ArgumentConsumer::consume`] never returns None after mutating args. async fn suggest<'a>( - &self, + &'a self, sender: &CommandSender<'a>, server: &'a Server, input: &'a str, - ) -> Result>>, CommandError>; + ) -> Result>, CommandError>; } pub(crate) trait GetClientSideArgParser { @@ -67,10 +67,7 @@ pub(crate) trait GetClientSideArgParser { } pub(crate) trait DefaultNameArgConsumer: ArgumentConsumer { - fn default_name(&self) -> &'static str; - - /// needed because trait upcasting is not stable - fn get_argument_consumer(&self) -> &dyn ArgumentConsumer; + fn default_name(&self) -> String; } #[derive(Clone)] @@ -83,7 +80,7 @@ pub(crate) enum Arg<'a> { Pos2D(Vector2), Rotation(f32, f32), GameMode(GameMode), - CommandTree(CommandTree<'a>), + CommandTree(CommandTree), Item(&'a str), ResourceLocation(&'a str), Block(&'a str), @@ -112,7 +109,7 @@ impl GetCloned for HashMap { pub(crate) trait FindArg<'a> { type Data; - fn find_arg(args: &'a ConsumedArgs, name: &'a str) -> Result; + fn find_arg(args: &'a ConsumedArgs, name: &str) -> Result; } pub(crate) trait FindArgDefaultName<'a, T> { @@ -121,7 +118,7 @@ pub(crate) trait FindArgDefaultName<'a, T> { impl<'a, T, C: FindArg<'a, Data = T> + DefaultNameArgConsumer> FindArgDefaultName<'a, T> for C { fn find_arg_default_name(&self, args: &'a ConsumedArgs) -> Result { - C::find_arg(args, self.default_name()) + C::find_arg(args, &self.default_name()) } } diff --git a/pumpkin/src/command/client_cmd_suggestions.rs b/pumpkin/src/command/client_cmd_suggestions.rs index 7c8c7b2f..707dfcf5 100644 --- a/pumpkin/src/command/client_cmd_suggestions.rs +++ b/pumpkin/src/command/client_cmd_suggestions.rs @@ -10,10 +10,7 @@ use super::{ tree::{Node, NodeType}, }; -pub async fn send_c_commands_packet<'a>( - player: &Arc, - dispatcher: &RwLock>, -) { +pub async fn send_c_commands_packet(player: &Arc, dispatcher: &RwLock) { let cmd_src = super::CommandSender::Player(player.clone()); let mut first_level = Vec::new(); @@ -74,7 +71,7 @@ impl<'a> ProtoNodeBuilder<'a> { fn nodes_to_proto_node_builders<'a>( cmd_src: &super::CommandSender, - nodes: &[Node<'a>], + nodes: &'a [Node], children: &[usize], ) -> (bool, Vec>) { let mut child_nodes = Vec::new(); @@ -82,7 +79,7 @@ fn nodes_to_proto_node_builders<'a>( for i in children { let node = &nodes[*i]; - match node.node_type { + match &node.node_type { NodeType::Argument { name, consumer } => { let (node_is_executable, node_children) = nodes_to_proto_node_builders(cmd_src, nodes, &node.children); diff --git a/pumpkin/src/command/commands/cmd_bossbar.rs b/pumpkin/src/command/commands/cmd_bossbar.rs index 9caaea21..25e449a7 100644 --- a/pumpkin/src/command/commands/cmd_bossbar.rs +++ b/pumpkin/src/command/commands/cmd_bossbar.rs @@ -28,10 +28,12 @@ const ARG_NAME: &str = "name"; const ARG_VISIBLE: &str = "visible"; -const AUTOCOMPLETE_CONSUMER: ResourceLocationArgumentConsumer = - ResourceLocationArgumentConsumer::new(true); -const NON_AUTOCOMPLETE_CONSUMER: ResourceLocationArgumentConsumer = - ResourceLocationArgumentConsumer::new(false); +const fn autocomplete_consumer() -> ResourceLocationArgumentConsumer { + ResourceLocationArgumentConsumer::new(true) +} +const fn non_autocomplete_consumer() -> ResourceLocationArgumentConsumer { + ResourceLocationArgumentConsumer::new(false) +} enum CommandValueGet { Max, @@ -61,7 +63,7 @@ impl CommandExecutor for BossbarAddExecuter { server: &Server, args: &ConsumedArgs<'a>, ) -> Result<(), CommandError> { - let namespace = NON_AUTOCOMPLETE_CONSUMER.find_arg_default_name(args)?; + let namespace = non_autocomplete_consumer().find_arg_default_name(args)?; let Some(Arg::Simple(name)) = args.get(ARG_NAME) else { return Err(InvalidConsumption(Some(ARG_NAME.into()))); }; @@ -96,7 +98,7 @@ impl CommandExecutor for BossbarGetExecuter { server: &Server, args: &ConsumedArgs<'a>, ) -> Result<(), CommandError> { - let namespace = AUTOCOMPLETE_CONSUMER.find_arg_default_name(args)?; + let namespace = autocomplete_consumer().find_arg_default_name(args)?; let Some(bossbar) = server.bossbars.lock().await.get_bossbar(namespace) else { send_error_message( @@ -197,7 +199,7 @@ impl CommandExecutor for BossbarRemoveExecuter { server: &Server, args: &ConsumedArgs<'a>, ) -> Result<(), CommandError> { - let namespace = AUTOCOMPLETE_CONSUMER.find_arg_default_name(args)?; + let namespace = autocomplete_consumer().find_arg_default_name(args)?; if !server.bossbars.lock().await.has_bossbar(namespace) { send_error_message( @@ -237,7 +239,7 @@ impl CommandExecutor for BossbarSetExecuter { server: &Server, args: &ConsumedArgs<'a>, ) -> Result<(), CommandError> { - let namespace = AUTOCOMPLETE_CONSUMER.find_arg_default_name(args)?; + let namespace = autocomplete_consumer().find_arg_default_name(args)?; let Some(bossbar) = server.bossbars.lock().await.get_bossbar(namespace) else { handle_bossbar_error( @@ -275,10 +277,10 @@ impl CommandExecutor for BossbarSetExecuter { Ok(()) } CommandValueSet::Max => { - let Ok(max_value) = MAX_VALUE_CONSUMER.find_arg_default_name(args)? else { + let Ok(max_value) = max_value_consumer().find_arg_default_name(args)? else { send_error_message( sender, - format!("{} is out of bounds.", MAX_VALUE_CONSUMER.default_name()), + format!("{} is out of bounds.", max_value_consumer().default_name()), ) .await; return Ok(()); @@ -423,10 +425,10 @@ impl CommandExecutor for BossbarSetExecuter { Ok(()) } CommandValueSet::Value => { - let Ok(value) = VALUE_CONSUMER.find_arg_default_name(args)? else { + let Ok(value) = value_consumer().find_arg_default_name(args)? else { send_error_message( sender, - format!("{} is out of bounds.", VALUE_CONSUMER.default_name()), + format!("{} is out of bounds.", value_consumer().default_name()), ) .await; return Ok(()); @@ -488,85 +490,86 @@ impl CommandExecutor for BossbarSetExecuter { } } -static MAX_VALUE_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new().min(0).name("max"); +fn max_value_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new().min(0).name("max") +} -static VALUE_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new().min(0).name("value"); +fn value_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new().min(0).name("value") +} -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION) .with_child( literal("add").with_child( - argument_default_name(&NON_AUTOCOMPLETE_CONSUMER).with_child( - argument(ARG_NAME, &SimpleArgConsumer).execute(&BossbarAddExecuter), - ), + argument_default_name(non_autocomplete_consumer()) + .with_child(argument(ARG_NAME, SimpleArgConsumer).execute(BossbarAddExecuter)), ), ) .with_child( literal("get").with_child( - argument_default_name(&AUTOCOMPLETE_CONSUMER) - .with_child(literal("max").execute(&BossbarGetExecuter(CommandValueGet::Max))) + argument_default_name(autocomplete_consumer()) + .with_child(literal("max").execute(BossbarGetExecuter(CommandValueGet::Max))) .with_child( - literal("players").execute(&BossbarGetExecuter(CommandValueGet::Players)), + literal("players").execute(BossbarGetExecuter(CommandValueGet::Players)), ) .with_child( - literal("value").execute(&BossbarGetExecuter(CommandValueGet::Value)), + literal("value").execute(BossbarGetExecuter(CommandValueGet::Value)), ) .with_child( - literal("visible").execute(&BossbarGetExecuter(CommandValueGet::Visible)), + literal("visible").execute(BossbarGetExecuter(CommandValueGet::Visible)), ), ), ) - .with_child(literal("list").execute(&BossbarListExecuter)) + .with_child(literal("list").execute(BossbarListExecuter)) .with_child(literal("remove").with_child( - argument_default_name(&AUTOCOMPLETE_CONSUMER).execute(&BossbarRemoveExecuter), + argument_default_name(autocomplete_consumer()).execute(BossbarRemoveExecuter), )) .with_child( literal("set").with_child( - argument_default_name(&AUTOCOMPLETE_CONSUMER) + argument_default_name(autocomplete_consumer()) .with_child( literal("color").with_child( - argument_default_name(&BossbarColorArgumentConsumer) - .execute(&BossbarSetExecuter(CommandValueSet::Color)), + argument_default_name(BossbarColorArgumentConsumer) + .execute(BossbarSetExecuter(CommandValueSet::Color)), ), ) .with_child( literal("max").with_child( - argument_default_name(&MAX_VALUE_CONSUMER) - .execute(&BossbarSetExecuter(CommandValueSet::Max)), + argument_default_name(max_value_consumer()) + .execute(BossbarSetExecuter(CommandValueSet::Max)), ), ) .with_child( literal("name").with_child( - argument(ARG_NAME, &SimpleArgConsumer) - .execute(&BossbarSetExecuter(CommandValueSet::Name)), + argument(ARG_NAME, SimpleArgConsumer) + .execute(BossbarSetExecuter(CommandValueSet::Name)), ), ) .with_child( literal("players") .with_child( - argument_default_name(&PlayersArgumentConsumer) - .execute(&BossbarSetExecuter(CommandValueSet::Players(true))), + argument_default_name(PlayersArgumentConsumer) + .execute(BossbarSetExecuter(CommandValueSet::Players(true))), ) - .execute(&BossbarSetExecuter(CommandValueSet::Players(false))), + .execute(BossbarSetExecuter(CommandValueSet::Players(false))), ) .with_child( literal("style").with_child( - argument_default_name(&BossbarStyleArgumentConsumer) - .execute(&BossbarSetExecuter(CommandValueSet::Style)), + argument_default_name(BossbarStyleArgumentConsumer) + .execute(BossbarSetExecuter(CommandValueSet::Style)), ), ) .with_child( literal("value").with_child( - argument_default_name(&VALUE_CONSUMER) - .execute(&BossbarSetExecuter(CommandValueSet::Value)), + argument_default_name(value_consumer()) + .execute(BossbarSetExecuter(CommandValueSet::Value)), ), ) .with_child( literal("visible").with_child( - argument(ARG_VISIBLE, &BoolArgConsumer) - .execute(&BossbarSetExecuter(CommandValueSet::Visible)), + argument(ARG_VISIBLE, BoolArgConsumer) + .execute(BossbarSetExecuter(CommandValueSet::Visible)), ), ), ), diff --git a/pumpkin/src/command/commands/cmd_clear.rs b/pumpkin/src/command/commands/cmd_clear.rs index 07379587..b948d0df 100644 --- a/pumpkin/src/command/commands/cmd_clear.rs +++ b/pumpkin/src/command/commands/cmd_clear.rs @@ -107,8 +107,8 @@ impl CommandExecutor for ClearSelfExecutor { } #[allow(clippy::redundant_closure_for_method_calls)] // causes lifetime issues -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION) - .with_child(argument(ARG_TARGET, &EntitiesArgumentConsumer).execute(&ClearExecutor)) - .with_child(require(&|sender| sender.is_player()).execute(&ClearSelfExecutor)) + .with_child(argument(ARG_TARGET, EntitiesArgumentConsumer).execute(ClearExecutor)) + .with_child(require(|sender| sender.is_player()).execute(ClearSelfExecutor)) } diff --git a/pumpkin/src/command/commands/cmd_fill.rs b/pumpkin/src/command/commands/cmd_fill.rs index 1a01fb15..140e8729 100644 --- a/pumpkin/src/command/commands/cmd_fill.rs +++ b/pumpkin/src/command/commands/cmd_fill.rs @@ -154,23 +154,21 @@ impl CommandExecutor for SetblockExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| { - sender.has_permission_lvl(PermissionLvl::Two) && sender.world().is_some() - }) - .with_child( - argument(ARG_FROM, &BlockPosArgumentConsumer).with_child( - argument(ARG_TO, &BlockPosArgumentConsumer).with_child( - argument(ARG_BLOCK, &BlockArgumentConsumer) - .with_child(literal("destroy").execute(&SetblockExecutor(Mode::Destroy))) - .with_child(literal("hollow").execute(&SetblockExecutor(Mode::Hollow))) - .with_child(literal("keep").execute(&SetblockExecutor(Mode::Keep))) - .with_child(literal("outline").execute(&SetblockExecutor(Mode::Outline))) - .with_child(literal("replace").execute(&SetblockExecutor(Mode::Replace))) - .execute(&SetblockExecutor(Mode::Replace)), + require(|sender| sender.has_permission_lvl(PermissionLvl::Two) && sender.world().is_some()) + .with_child( + argument(ARG_FROM, BlockPosArgumentConsumer).with_child( + argument(ARG_TO, BlockPosArgumentConsumer).with_child( + argument(ARG_BLOCK, BlockArgumentConsumer) + .with_child(literal("destroy").execute(SetblockExecutor(Mode::Destroy))) + .with_child(literal("hollow").execute(SetblockExecutor(Mode::Hollow))) + .with_child(literal("keep").execute(SetblockExecutor(Mode::Keep))) + .with_child(literal("outline").execute(SetblockExecutor(Mode::Outline))) + .with_child(literal("replace").execute(SetblockExecutor(Mode::Replace))) + .execute(SetblockExecutor(Mode::Replace)), + ), ), ), - ), ) } diff --git a/pumpkin/src/command/commands/cmd_gamemode.rs b/pumpkin/src/command/commands/cmd_gamemode.rs index faab9537..2b627862 100644 --- a/pumpkin/src/command/commands/cmd_gamemode.rs +++ b/pumpkin/src/command/commands/cmd_gamemode.rs @@ -107,13 +107,13 @@ impl CommandExecutor for GamemodeTargetPlayer { } #[allow(clippy::redundant_closure_for_method_calls)] -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| sender.has_permission_lvl(PermissionLvl::Two)).with_child( - argument(ARG_GAMEMODE, &GamemodeArgumentConsumer) - .with_child(require(&|sender| sender.is_player()).execute(&GamemodeTargetSelf)) + require(|sender| sender.has_permission_lvl(PermissionLvl::Two)).with_child( + argument(ARG_GAMEMODE, GamemodeArgumentConsumer) + .with_child(require(|sender| sender.is_player()).execute(GamemodeTargetSelf)) .with_child( - argument(ARG_TARGET, &PlayersArgumentConsumer).execute(&GamemodeTargetPlayer), + argument(ARG_TARGET, PlayersArgumentConsumer).execute(GamemodeTargetPlayer), ), ), ) diff --git a/pumpkin/src/command/commands/cmd_give.rs b/pumpkin/src/command/commands/cmd_give.rs index 36edb640..cdc3334b 100644 --- a/pumpkin/src/command/commands/cmd_give.rs +++ b/pumpkin/src/command/commands/cmd_give.rs @@ -17,10 +17,12 @@ const DESCRIPTION: &str = "Give items to player(s)."; const ARG_ITEM: &str = "item"; -static ITEM_COUNT_CONSUMER: BoundedNumArgumentConsumer = BoundedNumArgumentConsumer::new() - .name("count") - .min(0) - .max(6400); +fn item_count_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new() + .name("count") + .min(0) + .max(6400) +} struct GiveExecutor; @@ -36,7 +38,7 @@ impl CommandExecutor for GiveExecutor { let (item_name, item) = ItemArgumentConsumer::find_arg(args, ARG_ITEM)?; - let item_count = match ITEM_COUNT_CONSUMER.find_arg_default_name(args) { + let item_count = match item_count_consumer().find_arg_default_name(args) { Err(_) => 1, Ok(Ok(count)) => count, Ok(Err(())) => { @@ -72,13 +74,13 @@ impl CommandExecutor for GiveExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| sender.has_permission_lvl(PermissionLvl::Two)).with_child( - argument_default_name(&PlayersArgumentConsumer).with_child( - argument(ARG_ITEM, &ItemArgumentConsumer) - .execute(&GiveExecutor) - .with_child(argument_default_name(&ITEM_COUNT_CONSUMER).execute(&GiveExecutor)), + require(|sender| sender.has_permission_lvl(PermissionLvl::Two)).with_child( + argument_default_name(PlayersArgumentConsumer).with_child( + argument(ARG_ITEM, ItemArgumentConsumer) + .execute(GiveExecutor) + .with_child(argument_default_name(item_count_consumer()).execute(GiveExecutor)), ), ), ) diff --git a/pumpkin/src/command/commands/cmd_help.rs b/pumpkin/src/command/commands/cmd_help.rs index e382febf..c0ab3eb7 100644 --- a/pumpkin/src/command/commands/cmd_help.rs +++ b/pumpkin/src/command/commands/cmd_help.rs @@ -22,8 +22,9 @@ const ARG_COMMAND: &str = "command"; const COMMANDS_PER_PAGE: i32 = 7; -static PAGE_NUMBER_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new().name("page").min(1); +fn page_number_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new().name("page").min(1) +} struct CommandHelpExecutor; @@ -41,7 +42,7 @@ impl CommandExecutor for CommandHelpExecutor { let command_names = tree.names.join(", /"); let usage = format!("{tree}"); - let description = tree.description; + let description = &tree.description; let header_text = format!(" Help - /{} ", tree.names[0]); @@ -107,7 +108,7 @@ impl CommandExecutor for BaseHelpExecutor { server: &Server, args: &ConsumedArgs<'a>, ) -> Result<(), CommandError> { - let page_number = match PAGE_NUMBER_CONSUMER.find_arg_default_name(args) { + let page_number = match page_number_consumer().find_arg_default_name(args) { Err(_) => 1, Ok(Ok(number)) => number, Ok(Err(())) => { @@ -131,7 +132,7 @@ impl CommandExecutor for BaseHelpExecutor { }) .collect(); - commands.sort_by(|a, b| a.names[0].cmp(b.names[0])); + commands.sort_by(|a, b| a.names[0].cmp(&b.names[0])); let total_pages = (commands.len().to_i32().unwrap() + COMMANDS_PER_PAGE - 1) / COMMANDS_PER_PAGE; @@ -183,7 +184,7 @@ impl CommandExecutor for BaseHelpExecutor { .color_named(NamedColor::Gold) .add_child(TextComponent::text(" - ").color_named(NamedColor::Yellow)) .add_child( - TextComponent::text_string(tree.description.to_owned() + "\n") + TextComponent::text_string(tree.description.clone() + "\n") .color_named(NamedColor::White), ) .add_child(TextComponent::text(" Usage: ").color_named(NamedColor::Yellow)) @@ -220,11 +221,9 @@ impl CommandExecutor for BaseHelpExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION) - .with_child( - argument(ARG_COMMAND, &CommandTreeArgumentConsumer).execute(&CommandHelpExecutor), - ) - .with_child(argument_default_name(&PAGE_NUMBER_CONSUMER).execute(&BaseHelpExecutor)) - .execute(&BaseHelpExecutor) + .with_child(argument(ARG_COMMAND, CommandTreeArgumentConsumer).execute(CommandHelpExecutor)) + .with_child(argument_default_name(page_number_consumer()).execute(BaseHelpExecutor)) + .execute(BaseHelpExecutor) } diff --git a/pumpkin/src/command/commands/cmd_kick.rs b/pumpkin/src/command/commands/cmd_kick.rs index d0a8eec9..8d77bf3d 100644 --- a/pumpkin/src/command/commands/cmd_kick.rs +++ b/pumpkin/src/command/commands/cmd_kick.rs @@ -49,7 +49,7 @@ impl CommandExecutor for KickExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION) - .with_child(argument(ARG_TARGET, &PlayersArgumentConsumer).execute(&KickExecutor)) + .with_child(argument(ARG_TARGET, PlayersArgumentConsumer).execute(KickExecutor)) } diff --git a/pumpkin/src/command/commands/cmd_kill.rs b/pumpkin/src/command/commands/cmd_kill.rs index d763054b..2b36b0c4 100644 --- a/pumpkin/src/command/commands/cmd_kill.rs +++ b/pumpkin/src/command/commands/cmd_kill.rs @@ -65,8 +65,8 @@ impl CommandExecutor for KillSelfExecutor { } #[allow(clippy::redundant_closure_for_method_calls)] // causes lifetime issues -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION) - .with_child(argument(ARG_TARGET, &EntitiesArgumentConsumer).execute(&KillExecutor)) - .with_child(require(&|sender| sender.is_player()).execute(&KillSelfExecutor)) + .with_child(argument(ARG_TARGET, EntitiesArgumentConsumer).execute(KillExecutor)) + .with_child(require(|sender| sender.is_player()).execute(KillSelfExecutor)) } diff --git a/pumpkin/src/command/commands/cmd_list.rs b/pumpkin/src/command/commands/cmd_list.rs index 5a81f8f9..bbcc3641 100644 --- a/pumpkin/src/command/commands/cmd_list.rs +++ b/pumpkin/src/command/commands/cmd_list.rs @@ -55,6 +55,6 @@ fn get_player_names(players: Vec>) -> String { names } -pub fn init_command_tree<'a>() -> CommandTree<'a> { - CommandTree::new(NAMES, DESCRIPTION).execute(&ListExecutor) +pub fn init_command_tree() -> CommandTree { + CommandTree::new(NAMES, DESCRIPTION).execute(ListExecutor) } diff --git a/pumpkin/src/command/commands/cmd_pumpkin.rs b/pumpkin/src/command/commands/cmd_pumpkin.rs index 3dad98ec..a76a1be9 100644 --- a/pumpkin/src/command/commands/cmd_pumpkin.rs +++ b/pumpkin/src/command/commands/cmd_pumpkin.rs @@ -92,6 +92,6 @@ impl CommandExecutor for PumpkinExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { - CommandTree::new(NAMES, DESCRIPTION).execute(&PumpkinExecutor) +pub fn init_command_tree() -> CommandTree { + CommandTree::new(NAMES, DESCRIPTION).execute(PumpkinExecutor) } diff --git a/pumpkin/src/command/commands/cmd_say.rs b/pumpkin/src/command/commands/cmd_say.rs index 66b74338..fad4b64b 100644 --- a/pumpkin/src/command/commands/cmd_say.rs +++ b/pumpkin/src/command/commands/cmd_say.rs @@ -43,9 +43,9 @@ impl CommandExecutor for SayExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| sender.has_permission_lvl(PermissionLvl::Two)) - .with_child(argument(ARG_MESSAGE, &MsgArgConsumer).execute(&SayExecutor)), + require(|sender| sender.has_permission_lvl(PermissionLvl::Two)) + .with_child(argument(ARG_MESSAGE, MsgArgConsumer).execute(SayExecutor)), ) } diff --git a/pumpkin/src/command/commands/cmd_seed.rs b/pumpkin/src/command/commands/cmd_seed.rs index fb93acb0..c4ffc375 100644 --- a/pumpkin/src/command/commands/cmd_seed.rs +++ b/pumpkin/src/command/commands/cmd_seed.rs @@ -54,10 +54,10 @@ impl CommandExecutor for PumpkinExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION) - .with_child(require(&|sender| { + .with_child(require(|sender| { sender.has_permission_lvl(PermissionLvl::Two) })) - .execute(&PumpkinExecutor) + .execute(PumpkinExecutor) } diff --git a/pumpkin/src/command/commands/cmd_setblock.rs b/pumpkin/src/command/commands/cmd_setblock.rs index 0dd6ec9f..8b7cf973 100644 --- a/pumpkin/src/command/commands/cmd_setblock.rs +++ b/pumpkin/src/command/commands/cmd_setblock.rs @@ -79,19 +79,17 @@ impl CommandExecutor for SetblockExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| { - sender.has_permission_lvl(PermissionLvl::Two) && sender.world().is_some() - }) - .with_child( - argument(ARG_BLOCK_POS, &BlockPosArgumentConsumer).with_child( - argument(ARG_BLOCK, &BlockArgumentConsumer) - .with_child(literal("replace").execute(&SetblockExecutor(Mode::Replace))) - .with_child(literal("destroy").execute(&SetblockExecutor(Mode::Destroy))) - .with_child(literal("keep").execute(&SetblockExecutor(Mode::Keep))) - .execute(&SetblockExecutor(Mode::Replace)), + require(|sender| sender.has_permission_lvl(PermissionLvl::Two) && sender.world().is_some()) + .with_child( + argument(ARG_BLOCK_POS, BlockPosArgumentConsumer).with_child( + argument(ARG_BLOCK, BlockArgumentConsumer) + .with_child(literal("replace").execute(SetblockExecutor(Mode::Replace))) + .with_child(literal("destroy").execute(SetblockExecutor(Mode::Destroy))) + .with_child(literal("keep").execute(SetblockExecutor(Mode::Keep))) + .execute(SetblockExecutor(Mode::Replace)), + ), ), - ), ) } diff --git a/pumpkin/src/command/commands/cmd_stop.rs b/pumpkin/src/command/commands/cmd_stop.rs index de7803b1..9e3ada0b 100644 --- a/pumpkin/src/command/commands/cmd_stop.rs +++ b/pumpkin/src/command/commands/cmd_stop.rs @@ -37,8 +37,8 @@ impl CommandExecutor for StopExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| sender.has_permission_lvl(PermissionLvl::Four)).execute(&StopExecutor), + require(|sender| sender.has_permission_lvl(PermissionLvl::Four)).execute(StopExecutor), ) } diff --git a/pumpkin/src/command/commands/cmd_teleport.rs b/pumpkin/src/command/commands/cmd_teleport.rs index 3bc4cf08..d9468147 100644 --- a/pumpkin/src/command/commands/cmd_teleport.rs +++ b/pumpkin/src/command/commands/cmd_teleport.rs @@ -237,41 +237,41 @@ impl CommandExecutor for TpSelfToPosExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| sender.has_permission_lvl(PermissionLvl::Two)) + require(|sender| sender.has_permission_lvl(PermissionLvl::Two)) .with_child( - argument(ARG_LOCATION, &Position3DArgumentConsumer).execute(&TpSelfToPosExecutor), + argument(ARG_LOCATION, Position3DArgumentConsumer).execute(TpSelfToPosExecutor), ) .with_child( - argument(ARG_DESTINATION, &EntityArgumentConsumer).execute(&TpSelfToEntityExecutor), + argument(ARG_DESTINATION, EntityArgumentConsumer).execute(TpSelfToEntityExecutor), ) .with_child( - argument(ARG_TARGETS, &EntitiesArgumentConsumer) + argument(ARG_TARGETS, EntitiesArgumentConsumer) .with_child( - argument(ARG_LOCATION, &Position3DArgumentConsumer) - .execute(&TpEntitiesToPosExecutor) + argument(ARG_LOCATION, Position3DArgumentConsumer) + .execute(TpEntitiesToPosExecutor) .with_child( - argument(ARG_ROTATION, &RotationArgumentConsumer) - .execute(&TpEntitiesToPosWithRotationExecutor), + argument(ARG_ROTATION, RotationArgumentConsumer) + .execute(TpEntitiesToPosWithRotationExecutor), ) .with_child( literal("facing") .with_child( literal("entity").with_child( - argument(ARG_FACING_ENTITY, &EntityArgumentConsumer) - .execute(&TpEntitiesToPosFacingEntityExecutor), + argument(ARG_FACING_ENTITY, EntityArgumentConsumer) + .execute(TpEntitiesToPosFacingEntityExecutor), ), ) .with_child( - argument(ARG_FACING_LOCATION, &Position3DArgumentConsumer) - .execute(&TpEntitiesToPosFacingPosExecutor), + argument(ARG_FACING_LOCATION, Position3DArgumentConsumer) + .execute(TpEntitiesToPosFacingPosExecutor), ), ), ) .with_child( - argument(ARG_DESTINATION, &EntityArgumentConsumer) - .execute(&TpEntitiesToEntityExecutor), + argument(ARG_DESTINATION, EntityArgumentConsumer) + .execute(TpEntitiesToEntityExecutor), ), ), ) diff --git a/pumpkin/src/command/commands/cmd_time.rs b/pumpkin/src/command/commands/cmd_time.rs index ad289401..669a3294 100644 --- a/pumpkin/src/command/commands/cmd_time.rs +++ b/pumpkin/src/command/commands/cmd_time.rs @@ -18,10 +18,12 @@ const NAMES: [&str; 1] = ["time"]; const DESCRIPTION: &str = "Query the world time."; // TODO: This should be either higher or not bounded -static ARG_NUMBER: BoundedNumArgumentConsumer = BoundedNumArgumentConsumer::new() - .name("time") - .min(0) - .max(24000); +fn arg_number() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new() + .name("time") + .min(0) + .max(24000) +} #[derive(Clone, Copy)] enum Mode { @@ -83,7 +85,7 @@ impl CommandExecutor for TimeChangeExecutor { server: &crate::server::Server, args: &ConsumedArgs<'a>, ) -> Result<(), CommandError> { - let time_count = match ARG_NUMBER.find_arg_default_name(args) { + let time_count = match arg_number().find_arg_default_name(args) { Err(_) => 1, Ok(Ok(count)) => count, Ok(Err(())) => { @@ -124,22 +126,20 @@ impl CommandExecutor for TimeChangeExecutor { } } -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| sender.has_permission_lvl(PermissionLvl::Two)) + require(|sender| sender.has_permission_lvl(PermissionLvl::Two)) .with_child(literal("add").with_child( - argument_default_name(&ARG_NUMBER).execute(&TimeChangeExecutor(Mode::Add)), + argument_default_name(arg_number()).execute(TimeChangeExecutor(Mode::Add)), )) .with_child( literal("query") - .with_child(literal("daytime").execute(&TimeQueryExecutor(QueryMode::DayTime))) - .with_child( - literal("gametime").execute(&TimeQueryExecutor(QueryMode::GameTime)), - ) - .with_child(literal("day").execute(&TimeQueryExecutor(QueryMode::Day))), + .with_child(literal("daytime").execute(TimeQueryExecutor(QueryMode::DayTime))) + .with_child(literal("gametime").execute(TimeQueryExecutor(QueryMode::GameTime))) + .with_child(literal("day").execute(TimeQueryExecutor(QueryMode::Day))), ) .with_child(literal("set").with_child( - argument_default_name(&ARG_NUMBER).execute(&TimeChangeExecutor(Mode::Set)), + argument_default_name(arg_number()).execute(TimeChangeExecutor(Mode::Set)), )), ) } diff --git a/pumpkin/src/command/commands/cmd_transfer.rs b/pumpkin/src/command/commands/cmd_transfer.rs index 7660b808..e35b0329 100644 --- a/pumpkin/src/command/commands/cmd_transfer.rs +++ b/pumpkin/src/command/commands/cmd_transfer.rs @@ -23,10 +23,12 @@ const ARG_HOSTNAME: &str = "hostname"; const ARG_PLAYERS: &str = "players"; -static PORT_CONSUMER: BoundedNumArgumentConsumer = BoundedNumArgumentConsumer::new() - .name("port") - .min(1) - .max(65535); +fn port_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new() + .name("port") + .min(1) + .max(65535) +} struct TransferTargetSelf; @@ -42,7 +44,7 @@ impl CommandExecutor for TransferTargetSelf { return Err(InvalidConsumption(Some(ARG_HOSTNAME.into()))); }; - let port = match PORT_CONSUMER.find_arg_default_name(args) { + let port = match port_consumer().find_arg_default_name(args) { Err(_) => 25565, Ok(Ok(count)) => count, Ok(Err(())) => { @@ -84,7 +86,7 @@ impl CommandExecutor for TransferTargetPlayer { return Err(InvalidConsumption(Some(ARG_HOSTNAME.into()))); }; - let port = match PORT_CONSUMER.find_arg_default_name(args) { + let port = match port_consumer().find_arg_default_name(args) { Err(_) => 25565, Ok(Ok(count)) => count, Ok(Err(())) => { @@ -117,19 +119,19 @@ impl CommandExecutor for TransferTargetPlayer { } #[allow(clippy::redundant_closure_for_method_calls)] -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(&|sender| sender.has_permission_lvl(PermissionLvl::Three)).with_child( - argument(ARG_HOSTNAME, &SimpleArgConsumer) - .with_child(require(&|sender| sender.is_player()).execute(&TransferTargetSelf)) + require(|sender| sender.has_permission_lvl(PermissionLvl::Three)).with_child( + argument(ARG_HOSTNAME, SimpleArgConsumer) + .with_child(require(|sender| sender.is_player()).execute(TransferTargetSelf)) .with_child( - argument_default_name(&PORT_CONSUMER) + argument_default_name(port_consumer()) .with_child( - require(&|sender| sender.is_player()).execute(&TransferTargetSelf), + require(|sender| sender.is_player()).execute(TransferTargetSelf), ) .with_child( - argument(ARG_PLAYERS, &PlayersArgumentConsumer) - .execute(&TransferTargetPlayer), + argument(ARG_PLAYERS, PlayersArgumentConsumer) + .execute(TransferTargetPlayer), ), ), ), diff --git a/pumpkin/src/command/commands/cmd_worldborder.rs b/pumpkin/src/command/commands/cmd_worldborder.rs index fd9ae1a2..b52ac6b5 100644 --- a/pumpkin/src/command/commands/cmd_worldborder.rs +++ b/pumpkin/src/command/commands/cmd_worldborder.rs @@ -25,6 +25,28 @@ const NAMES: [&str; 1] = ["worldborder"]; const DESCRIPTION: &str = "Worldborder command."; +fn distance_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new().min(0.0).name("distance") +} + +fn time_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new().min(0).name("time") +} + +fn damage_per_block_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new() + .min(0.0) + .name("damage_per_block") +} + +fn damage_buffer_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new().min(0.0).name("buffer") +} + +fn warning_distance_consumer() -> BoundedNumArgumentConsumer { + BoundedNumArgumentConsumer::new().min(0).name("distance") +} + struct WorldborderGetExecutor; #[async_trait] @@ -67,12 +89,12 @@ impl CommandExecutor for WorldborderSetExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(distance) = DISTANCE_CONSUMER.find_arg_default_name(args)? else { + let Ok(distance) = distance_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - DISTANCE_CONSUMER.default_name() + distance_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -116,24 +138,24 @@ impl CommandExecutor for WorldborderSetTimeExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(distance) = DISTANCE_CONSUMER.find_arg_default_name(args)? else { + let Ok(distance) = distance_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - DISTANCE_CONSUMER.default_name() + distance_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) .await; return Ok(()); }; - let Ok(time) = TIME_CONSUMER.find_arg_default_name(args)? else { + let Ok(time) = time_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - TIME_CONSUMER.default_name() + time_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -188,12 +210,12 @@ impl CommandExecutor for WorldborderAddExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(distance) = DISTANCE_CONSUMER.find_arg_default_name(args)? else { + let Ok(distance) = distance_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - DISTANCE_CONSUMER.default_name() + distance_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -239,24 +261,24 @@ impl CommandExecutor for WorldborderAddTimeExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(distance) = DISTANCE_CONSUMER.find_arg_default_name(args)? else { + let Ok(distance) = distance_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - DISTANCE_CONSUMER.default_name() + distance_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) .await; return Ok(()); }; - let Ok(time) = TIME_CONSUMER.find_arg_default_name(args)? else { + let Ok(time) = time_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - TIME_CONSUMER.default_name() + time_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -341,12 +363,12 @@ impl CommandExecutor for WorldborderDamageAmountExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(damage_per_block) = DAMAGE_PER_BLOCK_CONSUMER.find_arg_default_name(args)? else { + let Ok(damage_per_block) = damage_per_block_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - DAMAGE_PER_BLOCK_CONSUMER.default_name() + damage_per_block_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -392,12 +414,12 @@ impl CommandExecutor for WorldborderDamageBufferExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(buffer) = DAMAGE_BUFFER_CONSUMER.find_arg_default_name(args)? else { + let Ok(buffer) = damage_buffer_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - DAMAGE_BUFFER_CONSUMER.default_name() + damage_buffer_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -443,12 +465,12 @@ impl CommandExecutor for WorldborderWarningDistanceExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(distance) = WARNING_DISTANCE_CONSUMER.find_arg_default_name(args)? else { + let Ok(distance) = warning_distance_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - WARNING_DISTANCE_CONSUMER.default_name() + warning_distance_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -494,12 +516,12 @@ impl CommandExecutor for WorldborderWarningTimeExecutor { .expect("There should always be atleast one world"); let mut border = world.worldborder.lock().await; - let Ok(time) = TIME_CONSUMER.find_arg_default_name(args)? else { + let Ok(time) = time_consumer().find_arg_default_name(args)? else { sender .send_message( TextComponent::text_string(format!( "{} is out of bounds.", - TIME_CONSUMER.default_name() + time_consumer().default_name() )) .color(Color::Named(NamedColor::Red)), ) @@ -529,59 +551,42 @@ impl CommandExecutor for WorldborderWarningTimeExecutor { } } -static DISTANCE_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new().min(0.0).name("distance"); - -static TIME_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new().min(0).name("time"); - -static DAMAGE_PER_BLOCK_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new() - .min(0.0) - .name("damage_per_block"); - -static DAMAGE_BUFFER_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new().min(0.0).name("buffer"); - -static WARNING_DISTANCE_CONSUMER: BoundedNumArgumentConsumer = - BoundedNumArgumentConsumer::new().min(0).name("distance"); - -pub fn init_command_tree<'a>() -> CommandTree<'a> { +pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION) .with_child( literal("add").with_child( - argument_default_name(&DISTANCE_CONSUMER) - .execute(&WorldborderAddExecutor) + argument_default_name(distance_consumer()) + .execute(WorldborderAddExecutor) .with_child( - argument_default_name(&TIME_CONSUMER).execute(&WorldborderAddTimeExecutor), + argument_default_name(time_consumer()).execute(WorldborderAddTimeExecutor), ), ), ) .with_child(literal("center").with_child( - argument_default_name(&Position2DArgumentConsumer).execute(&WorldborderCenterExecutor), + argument_default_name(Position2DArgumentConsumer).execute(WorldborderCenterExecutor), )) .with_child( literal("damage") .with_child( literal("amount").with_child( - argument_default_name(&DAMAGE_PER_BLOCK_CONSUMER) - .execute(&WorldborderDamageAmountExecutor), + argument_default_name(damage_per_block_consumer()) + .execute(WorldborderDamageAmountExecutor), ), ) .with_child( literal("buffer").with_child( - argument_default_name(&DAMAGE_BUFFER_CONSUMER) - .execute(&WorldborderDamageBufferExecutor), + argument_default_name(damage_buffer_consumer()) + .execute(WorldborderDamageBufferExecutor), ), ), ) - .with_child(literal("get").execute(&WorldborderGetExecutor)) + .with_child(literal("get").execute(WorldborderGetExecutor)) .with_child( literal("set").with_child( - argument_default_name(&DISTANCE_CONSUMER) - .execute(&WorldborderSetExecutor) + argument_default_name(distance_consumer()) + .execute(WorldborderSetExecutor) .with_child( - argument_default_name(&TIME_CONSUMER).execute(&WorldborderSetTimeExecutor), + argument_default_name(time_consumer()).execute(WorldborderSetTimeExecutor), ), ), ) @@ -589,12 +594,12 @@ pub fn init_command_tree<'a>() -> CommandTree<'a> { literal("warning") .with_child( literal("distance").with_child( - argument_default_name(&WARNING_DISTANCE_CONSUMER) - .execute(&WorldborderWarningDistanceExecutor), + argument_default_name(warning_distance_consumer()) + .execute(WorldborderWarningDistanceExecutor), ), ) .with_child(literal("time").with_child( - argument_default_name(&TIME_CONSUMER).execute(&WorldborderWarningTimeExecutor), + argument_default_name(time_consumer()).execute(WorldborderWarningTimeExecutor), )), ) } diff --git a/pumpkin/src/command/dispatcher.rs b/pumpkin/src/command/dispatcher.rs index b2dc27ae..4d1bb943 100644 --- a/pumpkin/src/command/dispatcher.rs +++ b/pumpkin/src/command/dispatcher.rs @@ -46,13 +46,13 @@ impl CommandError { } #[derive(Default)] -pub struct CommandDispatcher<'a> { - pub(crate) commands: HashMap<&'a str, Command<'a>>, +pub struct CommandDispatcher { + pub(crate) commands: HashMap, } /// Stores registered [`CommandTree`]s and dispatches commands to them. -impl<'a> CommandDispatcher<'a> { - pub async fn handle_command( +impl CommandDispatcher { + pub async fn handle_command<'a>( &'a self, sender: &mut CommandSender<'a>, server: &'a Server, @@ -81,7 +81,7 @@ impl<'a> CommandDispatcher<'a> { /// # todo /// - make this less ugly /// - do not query suggestions for the same consumer multiple times just because they are on different paths through the tree - pub(crate) async fn find_suggestions( + pub(crate) async fn find_suggestions<'a>( &'a self, src: &mut CommandSender<'a>, server: &'a Server, @@ -102,7 +102,7 @@ impl<'a> CommandDispatcher<'a> { // try paths and collect the nodes that fail // todo: make this more fine-grained for path in tree.iter_paths() { - match Self::try_find_suggestions_on_path(src, server, &path, &tree, &mut raw_args, cmd) + match Self::try_find_suggestions_on_path(src, server, &path, tree, &mut raw_args, cmd) .await { Err(InvalidConsumption(s)) => { @@ -129,12 +129,12 @@ impl<'a> CommandDispatcher<'a> { } let mut suggestions = Vec::from_iter(suggestions); - suggestions.sort_by(|a, b| a.suggestion.cmp(b.suggestion)); + suggestions.sort_by(|a, b| a.suggestion.cmp(&b.suggestion)); suggestions } /// Execute a command using its corresponding [`CommandTree`]. - pub(crate) async fn dispatch( + pub(crate) async fn dispatch<'a>( &'a self, src: &mut CommandSender<'a>, server: &'a Server, @@ -151,7 +151,7 @@ impl<'a> CommandDispatcher<'a> { // try paths until fitting path is found for path in tree.iter_paths() { - if Self::try_is_fitting_path(src, server, &path, &tree, &mut raw_args.clone()).await? { + if Self::try_is_fitting_path(src, server, &path, tree, &mut raw_args.clone()).await? { return Ok(()); } } @@ -160,14 +160,14 @@ impl<'a> CommandDispatcher<'a> { ))) } - pub(crate) fn get_tree(&self, key: &str) -> Result, CommandError> { + pub(crate) fn get_tree(&self, key: &str) -> Result<&CommandTree, CommandError> { let command = self .commands .get(key) .ok_or(GeneralCommandIssue("Command not found".to_string()))?; match command { - Command::Tree(tree) => Ok(tree.clone()), + Command::Tree(tree) => Ok(tree), Command::Alias(target) => { let Some(Command::Tree(tree)) = self.commands.get(target) else { log::error!("Error while parsing command alias \"{key}\": pointing to \"{target}\" which is not a valid tree"); @@ -175,22 +175,22 @@ impl<'a> CommandDispatcher<'a> { "Internal Error (See logs for details)".into(), )); }; - Ok(tree.clone()) + Ok(tree) } } } - async fn try_is_fitting_path( + async fn try_is_fitting_path<'a>( src: &mut CommandSender<'a>, server: &'a Server, path: &[usize], - tree: &CommandTree<'a>, + tree: &'a CommandTree, raw_args: &mut RawArgs<'a>, ) -> Result { let mut parsed_args: ConsumedArgs = HashMap::new(); for node in path.iter().map(|&i| &tree.nodes[i]) { - match node.node_type { + match &node.node_type { NodeType::ExecuteLeaf { executor } => { return if raw_args.is_empty() { executor.execute(src, server, &parsed_args).await?; @@ -223,18 +223,18 @@ impl<'a> CommandDispatcher<'a> { Ok(false) } - async fn try_find_suggestions_on_path( + async fn try_find_suggestions_on_path<'a>( src: &mut CommandSender<'a>, server: &'a Server, path: &[usize], - tree: &CommandTree<'a>, + tree: &'a CommandTree, raw_args: &mut RawArgs<'a>, input: &'a str, ) -> Result>>, CommandError> { let mut parsed_args: ConsumedArgs = HashMap::new(); for node in path.iter().map(|&i| &tree.nodes[i]) { - match node.node_type { + match &node.node_type { NodeType::ExecuteLeaf { .. } => { return Ok(None); } @@ -270,16 +270,18 @@ impl<'a> CommandDispatcher<'a> { } /// Register a command with the dispatcher. - pub(crate) fn register(&mut self, tree: CommandTree<'a>) { + pub(crate) fn register(&mut self, tree: CommandTree) { let mut names = tree.names.iter(); let primary_name = names.next().expect("at least one name must be provided"); - for &name in names { - self.commands.insert(name, Command::Alias(primary_name)); + for name in names { + self.commands + .insert(name.to_string(), Command::Alias(primary_name.to_string())); } - self.commands.insert(primary_name, Command::Tree(tree)); + self.commands + .insert(primary_name.to_string(), Command::Tree(tree)); } } diff --git a/pumpkin/src/command/mod.rs b/pumpkin/src/command/mod.rs index 9ab33038..11eea197 100644 --- a/pumpkin/src/command/mod.rs +++ b/pumpkin/src/command/mod.rs @@ -107,7 +107,7 @@ impl<'a> CommandSender<'a> { } #[must_use] -pub fn default_dispatcher<'a>() -> CommandDispatcher<'a> { +pub fn default_dispatcher() -> CommandDispatcher { let mut dispatcher = CommandDispatcher::default(); dispatcher.register(cmd_pumpkin::init_command_tree()); diff --git a/pumpkin/src/command/tree.rs b/pumpkin/src/command/tree.rs index 9ea18e35..8f54f949 100644 --- a/pumpkin/src/command/tree.rs +++ b/pumpkin/src/command/tree.rs @@ -1,34 +1,34 @@ use super::{args::ArgumentConsumer, CommandExecutor}; use crate::command::CommandSender; -use std::{collections::VecDeque, fmt::Debug}; +use std::{collections::VecDeque, fmt::Debug, sync::Arc}; /// see [`crate::commands::tree_builder::argument`] pub type RawArgs<'a> = Vec<&'a str>; #[derive(Debug, Clone)] -pub struct Node<'a> { +pub struct Node { pub(crate) children: Vec, - pub(crate) node_type: NodeType<'a>, + pub(crate) node_type: NodeType, } #[derive(Clone)] -pub enum NodeType<'a> { +pub enum NodeType { ExecuteLeaf { - executor: &'a dyn CommandExecutor, + executor: Arc, }, Literal { - string: &'a str, + string: String, }, Argument { - name: &'a str, - consumer: &'a dyn ArgumentConsumer, + name: String, + consumer: Arc, }, Require { - predicate: &'a (dyn Fn(&CommandSender) -> bool + Sync), + predicate: Arc bool + Send + Sync>, }, } -impl Debug for NodeType<'_> { +impl Debug for NodeType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::ExecuteLeaf { .. } => f @@ -46,28 +46,28 @@ impl Debug for NodeType<'_> { } } -pub enum Command<'a> { - Tree(CommandTree<'a>), - Alias(&'a str), +pub enum Command { + Tree(CommandTree), + Alias(String), } #[derive(Debug, Clone)] -pub struct CommandTree<'a> { - pub(crate) nodes: Vec>, +pub struct CommandTree { + pub(crate) nodes: Vec, pub(crate) children: Vec, - pub(crate) names: Vec<&'a str>, - pub(crate) description: &'a str, + pub(crate) names: Vec, + pub(crate) description: String, } -impl<'a> CommandTree<'a> { +impl CommandTree { /// iterate over all possible paths that end in a [`NodeType::ExecuteLeaf`] - pub(crate) fn iter_paths(&'a self) -> impl Iterator> + 'a { + pub(crate) fn iter_paths(&self) -> impl Iterator> + use<'_> { let mut todo = VecDeque::<(usize, usize)>::new(); // add root's children todo.extend(self.children.iter().map(|&i| (0, i))); - TraverseAllPathsIter::<'a> { + TraverseAllPathsIter { tree: self, path: Vec::::new(), todo, @@ -76,7 +76,7 @@ impl<'a> CommandTree<'a> { } struct TraverseAllPathsIter<'a> { - tree: &'a CommandTree<'a>, + tree: &'a CommandTree, path: Vec, /// (depth, i) todo: VecDeque<(usize, usize)>, diff --git a/pumpkin/src/command/tree_builder.rs b/pumpkin/src/command/tree_builder.rs index e750ea0b..92f65d9e 100644 --- a/pumpkin/src/command/tree_builder.rs +++ b/pumpkin/src/command/tree_builder.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::command::args::ArgumentConsumer; use crate::command::tree::{CommandTree, Node, NodeType}; use crate::command::CommandSender; @@ -5,9 +7,9 @@ use crate::command::CommandSender; use super::args::DefaultNameArgConsumer; use super::CommandExecutor; -impl<'a> CommandTree<'a> { +impl CommandTree { /// Add a child [Node] to the root of this [`CommandTree`]. - pub fn with_child(mut self, child: impl NodeBuilder<'a>) -> Self { + pub fn with_child(mut self, child: impl NodeBuilder) -> Self { let node = child.build(&mut self); self.children.push(self.nodes.len()); self.nodes.push(node); @@ -15,23 +17,17 @@ impl<'a> CommandTree<'a> { } /// provide at least one name - pub fn new( - names: [&'a str; NAME_COUNT], - description: &'a str, + pub fn new( + names: impl IntoIterator>, + description: impl Into, ) -> Self { - assert!(NAME_COUNT > 0); - - let mut names_vec = Vec::with_capacity(NAME_COUNT); - - for name in names { - names_vec.push(name); - } + let names_vec = names.into_iter().map(Into::into).collect(); Self { nodes: Vec::new(), children: Vec::new(), names: names_vec, - description, + description: description.into(), } } @@ -42,9 +38,11 @@ impl<'a> CommandTree<'a> { /// desired type. /// /// Also see [`NonLeafNodeBuilder::execute`]. - pub fn execute(mut self, executor: &'a dyn CommandExecutor) -> Self { + pub fn execute(mut self, executor: impl CommandExecutor + 'static + Send) -> Self { let node = Node { - node_type: NodeType::ExecuteLeaf { executor }, + node_type: NodeType::ExecuteLeaf { + executor: Arc::new(executor), + }, children: Vec::new(), }; @@ -55,16 +53,16 @@ impl<'a> CommandTree<'a> { } } -pub trait NodeBuilder<'a> { - fn build(self, tree: &mut CommandTree<'a>) -> Node<'a>; +pub trait NodeBuilder { + fn build(self, tree: &mut CommandTree) -> Node; } -struct LeafNodeBuilder<'a> { - node_type: NodeType<'a>, +struct LeafNodeBuilder { + node_type: NodeType, } -impl<'a> NodeBuilder<'a> for LeafNodeBuilder<'a> { - fn build(self, _tree: &mut CommandTree<'a>) -> Node<'a> { +impl NodeBuilder for LeafNodeBuilder { + fn build(self, _tree: &mut CommandTree) -> Node { Node { children: Vec::new(), node_type: self.node_type, @@ -72,14 +70,14 @@ impl<'a> NodeBuilder<'a> for LeafNodeBuilder<'a> { } } -pub struct NonLeafNodeBuilder<'a> { - node_type: NodeType<'a>, - child_nodes: Vec>, - leaf_nodes: Vec>, +pub struct NonLeafNodeBuilder { + node_type: NodeType, + child_nodes: Vec, + leaf_nodes: Vec, } -impl<'a> NodeBuilder<'a> for NonLeafNodeBuilder<'a> { - fn build(self, tree: &mut CommandTree<'a>) -> Node<'a> { +impl NodeBuilder for NonLeafNodeBuilder { + fn build(self, tree: &mut CommandTree) -> Node { let mut child_indices = Vec::new(); for node_builder in self.child_nodes { @@ -101,7 +99,7 @@ impl<'a> NodeBuilder<'a> for NonLeafNodeBuilder<'a> { } } -impl<'a> NonLeafNodeBuilder<'a> { +impl NonLeafNodeBuilder { /// Add a child [Node] to this one. pub fn with_child(mut self, child: Self) -> Self { self.child_nodes.push(child); @@ -115,9 +113,11 @@ impl<'a> NonLeafNodeBuilder<'a> { /// desired type. /// /// Also see [`CommandTree::execute`]. - pub fn execute(mut self, executor: &'a dyn CommandExecutor) -> Self { + pub fn execute(mut self, executor: impl CommandExecutor + 'static + Send) -> Self { self.leaf_nodes.push(LeafNodeBuilder { - node_type: NodeType::ExecuteLeaf { executor }, + node_type: NodeType::ExecuteLeaf { + executor: Arc::new(executor), + }, }); self @@ -125,9 +125,11 @@ impl<'a> NonLeafNodeBuilder<'a> { } /// Matches a sting literal. -pub const fn literal(string: &str) -> NonLeafNodeBuilder { +pub fn literal(string: impl Into) -> NonLeafNodeBuilder { NonLeafNodeBuilder { - node_type: NodeType::Literal { string }, + node_type: NodeType::Literal { + string: string.into(), + }, child_nodes: Vec::new(), leaf_nodes: Vec::new(), } @@ -141,20 +143,28 @@ pub const fn literal(string: &str) -> NonLeafNodeBuilder { /// [`NonLeafNodeBuilder::execute`] nodes in a [`ConsumedArgs`] instance. It must remove consumed arg(s) /// from [`RawArgs`] and return them. It must return None if [`RawArgs`] are invalid. [`RawArgs`] is /// reversed, so [`Vec::pop`] can be used to obtain args in ltr order. -pub fn argument<'a>(name: &'a str, consumer: &'a dyn ArgumentConsumer) -> NonLeafNodeBuilder<'a> { +pub fn argument( + name: impl Into, + consumer: impl ArgumentConsumer + 'static + Send, +) -> NonLeafNodeBuilder { NonLeafNodeBuilder { - node_type: NodeType::Argument { name, consumer }, + node_type: NodeType::Argument { + name: name.into(), + consumer: Arc::new(consumer), + }, child_nodes: Vec::new(), leaf_nodes: Vec::new(), } } /// same as [`crate::command::tree_builder::argument`], but uses default arg name of consumer -pub fn argument_default_name(consumer: &dyn DefaultNameArgConsumer) -> NonLeafNodeBuilder<'_> { +pub fn argument_default_name( + consumer: impl DefaultNameArgConsumer + 'static + Send, +) -> NonLeafNodeBuilder { NonLeafNodeBuilder { node_type: NodeType::Argument { name: consumer.default_name(), - consumer: consumer.get_argument_consumer(), + consumer: Arc::new(consumer), }, child_nodes: Vec::new(), leaf_nodes: Vec::new(), @@ -163,9 +173,13 @@ pub fn argument_default_name(consumer: &dyn DefaultNameArgConsumer) -> NonLeafNo /// ```predicate``` should return ```false``` if requirement for reaching following [Node]s is not /// met. -pub fn require(predicate: &(dyn Fn(&CommandSender) -> bool + Sync)) -> NonLeafNodeBuilder { +pub fn require( + predicate: impl Fn(&CommandSender) -> bool + Send + Sync + 'static, +) -> NonLeafNodeBuilder { NonLeafNodeBuilder { - node_type: NodeType::Require { predicate }, + node_type: NodeType::Require { + predicate: Arc::new(predicate), + }, child_nodes: Vec::new(), leaf_nodes: Vec::new(), } diff --git a/pumpkin/src/command/tree_format.rs b/pumpkin/src/command/tree_format.rs index 406d95f2..597aece0 100644 --- a/pumpkin/src/command/tree_format.rs +++ b/pumpkin/src/command/tree_format.rs @@ -7,7 +7,7 @@ trait IsVisible { fn is_visible(&self) -> bool; } -impl IsVisible for Node<'_> { +impl IsVisible for Node { fn is_visible(&self) -> bool { matches!( self.node_type, @@ -16,9 +16,9 @@ impl IsVisible for Node<'_> { } } -impl Display for Node<'_> { +impl Display for Node { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self.node_type { + match &self.node_type { NodeType::Literal { string } => { f.write_str(string)?; } @@ -50,10 +50,10 @@ fn flatten_require_nodes(nodes: &[Node], children: &[usize]) -> Vec { new_children } -impl Display for CommandTree<'_> { +impl Display for CommandTree { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_char('/')?; - f.write_str(self.names[0])?; + f.write_str(&self.names[0])?; let mut todo = VecDeque::<&[usize]>::with_capacity(self.children.len()); todo.push_back(&self.children); diff --git a/pumpkin/src/server/mod.rs b/pumpkin/src/server/mod.rs index cb5c57b1..2ae5804f 100644 --- a/pumpkin/src/server/mod.rs +++ b/pumpkin/src/server/mod.rs @@ -47,7 +47,7 @@ pub struct Server { /// Saves server branding information. server_branding: CachedBranding, /// Saves and Dispatches commands to appropriate handlers. - pub command_dispatcher: RwLock>, + pub command_dispatcher: RwLock, /// Saves and calls blocks blocks pub block_manager: Arc, /// Manages multiple worlds within the server.