From fb13004b47a6c3f85158e29460f51fcadc871c45 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Wed, 28 Jan 2026 00:52:47 +0100 Subject: [PATCH] fix: apply clippy lints to workspace also add contributors to /pumpkin command Co-Authored-By: Fyor <90567841+fyordev@users.noreply.github.com> Co-Authored-By: MartV0 <34748938+martv0@users.noreply.github.com> Co-Authored-By: FabseGP --- Cargo.toml | 46 ++- pumpkin-api-macros/Cargo.toml | 3 + pumpkin-config/Cargo.toml | 3 + pumpkin-config/src/chunk.rs | 6 +- pumpkin-config/src/lib.rs | 30 +- pumpkin-config/src/networking/auth.rs | 6 +- pumpkin-config/src/networking/compression.rs | 2 +- pumpkin-config/src/networking/query.rs | 2 +- pumpkin-config/src/networking/rcon.rs | 6 +- pumpkin-config/src/op.rs | 1 + pumpkin-config/src/resource_pack.rs | 2 +- pumpkin-config/src/server_links.rs | 18 +- pumpkin-data/Cargo.toml | 4 + pumpkin-data/build/biome.rs | 26 +- pumpkin-data/build/bitsets.rs | 2 +- pumpkin-data/build/block.rs | 96 +++--- pumpkin-data/build/build.rs | 3 +- pumpkin-data/build/chunk_status.rs | 2 +- pumpkin-data/build/damage_type.rs | 22 +- pumpkin-data/build/data_component.rs | 2 +- pumpkin-data/build/dimension.rs | 9 +- pumpkin-data/build/effect.rs | 10 +- pumpkin-data/build/enchantments.rs | 32 +- pumpkin-data/build/entity_type.rs | 41 +-- pumpkin-data/build/fluid.rs | 27 +- pumpkin-data/build/item.rs | 46 ++- pumpkin-data/build/loot.rs | 184 ++++++------ pumpkin-data/build/message_type.rs | 2 +- pumpkin-data/build/noise_parameter.rs | 2 +- pumpkin-data/build/noise_router.rs | 34 +-- pumpkin-data/build/packet.rs | 4 +- pumpkin-data/build/potion.rs | 4 +- pumpkin-data/build/potion_brewing.rs | 4 +- pumpkin-data/build/recipes.rs | 52 ++-- pumpkin-data/build/registry.rs | 3 +- pumpkin-data/build/tag.rs | 8 +- pumpkin-data/build/tracked_data.rs | 2 +- pumpkin-data/src/block_direction.rs | 207 +++++++------ pumpkin-data/src/block_state.rs | 32 +- pumpkin-data/src/blocks.rs | 5 +- pumpkin-data/src/collision_shape.rs | 10 +- pumpkin-data/src/data_component_impl.rs | 34 ++- pumpkin-inventory/Cargo.toml | 3 + pumpkin-inventory/src/container_click.rs | 24 +- .../src/crafting/crafting_inventory.rs | 5 +- .../src/crafting/crafting_screen_handler.rs | 17 +- pumpkin-inventory/src/crafting/recipes.rs | 4 +- pumpkin-inventory/src/double.rs | 4 +- pumpkin-inventory/src/entity_equipment.rs | 2 + .../furnace_like_screen_handler.rs | 13 +- .../src/generic_container_screen_handler.rs | 2 +- pumpkin-inventory/src/lib.rs | 1 + .../src/player/ender_chest_inventory.rs | 5 +- .../src/player/player_inventory.rs | 33 +- .../src/player/player_screen_handler.rs | 8 +- pumpkin-inventory/src/screen_handler.rs | 71 ++--- pumpkin-inventory/src/slot.rs | 9 +- pumpkin-inventory/src/sync_handler.rs | 3 +- pumpkin-inventory/src/window_property.rs | 8 +- pumpkin-macros/Cargo.toml | 3 + pumpkin-macros/src/lib.rs | 28 +- pumpkin-nbt/Cargo.toml | 3 + pumpkin-nbt/src/compound.rs | 101 ++++--- pumpkin-nbt/src/deserializer.rs | 12 +- pumpkin-nbt/src/lib.rs | 41 +-- pumpkin-nbt/src/nbt_compress.rs | 20 +- pumpkin-nbt/src/serializer.rs | 93 +++--- pumpkin-nbt/src/tag.rs | 171 ++++++----- pumpkin-protocol/Cargo.toml | 3 + pumpkin-protocol/src/bedrock/ack.rs | 7 +- .../src/bedrock/client/disconnect_player.rs | 1 + .../src/bedrock/client/handshake.rs | 1 + .../src/bedrock/client/inventory_content.rs | 2 +- .../src/bedrock/client/level_chunk.rs | 6 +- .../client/network_chunk_publisher_update.rs | 1 + .../src/bedrock/client/network_settings.rs | 1 + .../src/bedrock/client/raknet/connection.rs | 14 +- .../bedrock/client/raknet/open_connection.rs | 2 + .../bedrock/client/raknet/unconnected_pong.rs | 1 + .../src/bedrock/client/resource_pack_stack.rs | 1 + .../src/bedrock/client/resource_packs_info.rs | 2 + .../src/bedrock/client/set_actor_data.rs | 1 + .../src/bedrock/client/set_time.rs | 1 + pumpkin-protocol/src/bedrock/frame_set.rs | 10 +- pumpkin-protocol/src/bedrock/mod.rs | 63 ++-- .../src/bedrock/packet_decoder.rs | 17 +- .../src/bedrock/packet_encoder.rs | 15 +- .../src/bedrock/server/loading_screen.rs | 1 + pumpkin-protocol/src/bedrock/server/text.rs | 7 +- .../src/codec/bedrock_block_pos.rs | 2 +- pumpkin-protocol/src/codec/bit_set.rs | 2 +- pumpkin-protocol/src/codec/bitset.rs | 14 +- pumpkin-protocol/src/codec/data_component.rs | 2 +- .../src/codec/item_stack_seralizer.rs | 19 +- pumpkin-protocol/src/codec/optional_int.rs | 5 +- pumpkin-protocol/src/codec/u24_type.rs | 2 +- pumpkin-protocol/src/codec/var_int.rs | 17 +- pumpkin-protocol/src/codec/var_long.rs | 14 +- pumpkin-protocol/src/codec/var_uint.rs | 17 +- pumpkin-protocol/src/codec/var_ulong.rs | 27 +- pumpkin-protocol/src/codec/velocity.rs | 49 +-- .../java/client/config/add_resource_pack.rs | 1 + .../java/client/config/config_disconnect.rs | 1 + .../src/java/client/config/cookie_request.rs | 1 + .../src/java/client/config/known_packs.rs | 1 + .../src/java/client/config/plugin_message.rs | 1 + .../src/java/client/config/registry_data.rs | 9 +- .../src/java/client/config/server_links.rs | 1 + .../src/java/client/config/store_cookie.rs | 1 + .../src/java/client/config/transfer.rs | 1 + .../src/java/client/config/update_tags.rs | 1 + .../src/java/client/login/cookie_request.rs | 1 + .../java/client/login/encryption_request.rs | 1 + .../src/java/client/login/login_disconnect.rs | 1 + .../src/java/client/login/login_success.rs | 1 + .../src/java/client/login/plugin_request.rs | 1 + .../src/java/client/login/set_compression.rs | 1 + .../src/java/client/play/acknowledge_block.rs | 1 + .../src/java/client/play/actionbar.rs | 1 + .../java/client/play/block_destroy_stage.rs | 1 + .../src/java/client/play/block_entity_data.rs | 1 + .../src/java/client/play/block_event.rs | 1 + .../src/java/client/play/block_update.rs | 1 + .../src/java/client/play/boss_event.rs | 1 + .../src/java/client/play/change_difficulty.rs | 1 + .../src/java/client/play/chunk_batch_end.rs | 1 + .../src/java/client/play/chunk_data.rs | 3 +- .../src/java/client/play/clear_title.rs | 1 + .../src/java/client/play/close_container.rs | 1 + .../src/java/client/play/combat_death.rs | 1 + .../java/client/play/command_suggestions.rs | 2 + .../src/java/client/play/commands.rs | 16 +- .../src/java/client/play/cookie_request.rs | 1 + .../src/java/client/play/damage_event.rs | 1 + .../src/java/client/play/disconnect.rs | 1 + .../client/play/disguised_chat_message.rs | 1 + .../src/java/client/play/display_objective.rs | 1 + .../src/java/client/play/entity_animation.rs | 1 + .../src/java/client/play/entity_metadata.rs | 3 +- .../java/client/play/entity_position_sync.rs | 1 + .../java/client/play/entity_sound_effect.rs | 3 +- .../src/java/client/play/entity_status.rs | 1 + .../src/java/client/play/entity_velocity.rs | 1 + .../src/java/client/play/explode.rs | 1 + .../src/java/client/play/game_event.rs | 1 + .../src/java/client/play/head_rot.rs | 1 + .../src/java/client/play/hurt_animation.rs | 1 + .../client/play/initialize_world_border.rs | 1 + .../src/java/client/play/keep_alive.rs | 1 + .../src/java/client/play/level_event.rs | 1 + .../src/java/client/play/login.rs | 2 + .../java/client/play/multi_block_update.rs | 54 ++-- .../src/java/client/play/open_screen.rs | 1 + .../src/java/client/play/open_sign_editor.rs | 1 + .../src/java/client/play/particle.rs | 1 + .../src/java/client/play/ping_response.rs | 1 + .../src/java/client/play/player_abilities.rs | 1 + .../java/client/play/player_chat_message.rs | 3 +- .../java/client/play/player_info_update.rs | 3 +- .../src/java/client/play/player_position.rs | 1 + .../src/java/client/play/player_remove.rs | 1 + .../java/client/play/player_spawn_position.rs | 3 +- .../src/java/client/play/remove_entities.rs | 1 + .../src/java/client/play/remove_mob_effect.rs | 1 + .../src/java/client/play/reset_score.rs | 1 + .../src/java/client/play/respawn.rs | 1 + .../src/java/client/play/server_links.rs | 1 + .../src/java/client/play/set_border_center.rs | 1 + .../java/client/play/set_border_lerp_size.rs | 1 + .../src/java/client/play/set_border_size.rs | 1 + .../client/play/set_border_warning_delay.rs | 1 + .../play/set_border_warning_distance.rs | 1 + .../java/client/play/set_container_content.rs | 1 + .../client/play/set_container_property.rs | 1 + .../java/client/play/set_container_slot.rs | 1 + .../src/java/client/play/set_cursor_slot.rs | 1 + .../src/java/client/play/set_equipment.rs | 7 +- .../src/java/client/play/set_experience.rs | 3 +- .../src/java/client/play/set_health.rs | 1 + .../src/java/client/play/set_held_item.rs | 1 + .../java/client/play/set_player_inventory.rs | 1 + .../src/java/client/play/set_time.rs | 1 + .../src/java/client/play/set_title.rs | 1 + .../java/client/play/set_title_animation.rs | 1 + .../src/java/client/play/sound_effect.rs | 1 + .../src/java/client/play/spawn_entity.rs | 1 + .../src/java/client/play/stop_sound.rs | 4 +- .../src/java/client/play/store_cookie.rs | 1 + .../src/java/client/play/subtitle.rs | 1 + .../java/client/play/system_chat_message.rs | 1 + .../src/java/client/play/take_item.rs | 1 + .../src/java/client/play/teleport_entity.rs | 1 + .../src/java/client/play/ticking_state.rs | 1 + .../src/java/client/play/ticking_step.rs | 1 + .../src/java/client/play/transfer.rs | 1 + .../src/java/client/play/unload_chunk.rs | 1 + .../src/java/client/play/update_entity_pos.rs | 1 + .../java/client/play/update_entity_pos_rot.rs | 1 + .../src/java/client/play/update_entity_rot.rs | 1 + .../src/java/client/play/update_mob_effect.rs | 1 + .../src/java/client/play/update_objectives.rs | 1 + .../src/java/client/play/update_score.rs | 1 + .../src/java/client/play/worldevent.rs | 1 + .../src/java/client/status/ping_response.rs | 1 + .../src/java/client/status/status_response.rs | 1 + pumpkin-protocol/src/java/packet_decoder.rs | 28 +- pumpkin-protocol/src/java/packet_encoder.rs | 19 +- .../java/server/config/client_information.rs | 2 +- .../src/java/server/config/plugin_message.rs | 2 +- .../server/config/resource_pack_response.rs | 3 +- .../src/java/server/login/plugin_response.rs | 2 +- .../src/java/server/play/custom_payload.rs | 5 +- .../src/java/server/play/interact.rs | 6 +- .../src/java/server/play/player_action.rs | 1 + .../src/java/server/play/player_position.rs | 2 +- .../server/play/player_position_rotation.rs | 2 +- pumpkin-protocol/src/lib.rs | 41 +-- pumpkin-protocol/src/query.rs | 17 +- pumpkin-protocol/src/ser/deserializer.rs | 23 +- pumpkin-protocol/src/ser/mod.rs | 16 +- pumpkin-protocol/src/ser/serializer.rs | 2 +- pumpkin-protocol/src/serial/deserializer.rs | 14 +- pumpkin-protocol/src/serial/serializer.rs | 8 +- pumpkin-util/Cargo.toml | 3 + pumpkin-util/src/biome.rs | 5 +- pumpkin-util/src/gamemode.rs | 1 + pumpkin-util/src/lib.rs | 13 +- pumpkin-util/src/loot_table.rs | 10 +- pumpkin-util/src/math/block_box.rs | 27 +- pumpkin-util/src/math/boundingbox.rs | 50 +++- pumpkin-util/src/math/euler_angle.rs | 11 +- pumpkin-util/src/math/experience.rs | 11 +- pumpkin-util/src/math/float_provider.rs | 38 ++- pumpkin-util/src/math/int_provider.rs | 50 +++- pumpkin-util/src/math/mod.rs | 20 +- pumpkin-util/src/math/pool.rs | 15 +- pumpkin-util/src/math/position.rs | 65 ++-- pumpkin-util/src/math/vector2.rs | 29 +- pumpkin-util/src/math/vector3.rs | 53 ++-- pumpkin-util/src/noise/mod.rs | 1 + pumpkin-util/src/noise/perlin.rs | 37 ++- pumpkin-util/src/noise/simplex.rs | 47 +-- pumpkin-util/src/permission.rs | 25 +- pumpkin-util/src/random/legacy_rand.rs | 28 +- pumpkin-util/src/random/mod.rs | 16 +- pumpkin-util/src/random/xoroshiro128.rs | 17 +- pumpkin-util/src/registry.rs | 24 +- pumpkin-util/src/resource_location.rs | 9 +- pumpkin-util/src/text/color.rs | 95 +++--- pumpkin-util/src/text/hover.rs | 3 +- pumpkin-util/src/text/mod.rs | 109 ++++--- pumpkin-util/src/text/style.rs | 12 + pumpkin-util/src/translation.rs | 281 +++++++++--------- pumpkin-util/src/version.rs | 2 + pumpkin-util/src/world_seed.rs | 12 +- pumpkin/Cargo.toml | 3 + pumpkin/src/command/commands/pumpkin.rs | 88 +++++- pumpkin/src/lib.rs | 69 +++-- pumpkin/src/main.rs | 37 --- pumpkin/src/net/bedrock/mod.rs | 19 +- pumpkin/src/net/bedrock/play.rs | 10 +- pumpkin/src/net/java/play.rs | 29 +- pumpkin/src/world/mod.rs | 7 +- 263 files changed, 2173 insertions(+), 1651 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 93206c623..5dbc023c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,50 @@ members = [ "pumpkin-data", ] + +[workspace.lints.clippy] +# Groups +all = { level = "deny", priority = -1 } +# nursery = { level = "deny", priority = -1 } +pedantic = { level = "deny", priority = -1 } +cargo = { level = "deny", priority = -1 } + +if_then_some_else_none = "deny" +empty_enum_variants_with_brackets = "deny" +empty_structs_with_brackets = "deny" +separated_literal_suffix = "deny" +semicolon_outside_block = "deny" +non_zero_suggestions = "deny" +string_lit_chars_any = "deny" +use_self = "deny" +useless_let_if_seq = "deny" +branches_sharing_code = "deny" +equatable_if_let = "deny" +option_if_let_else = "deny" +needless_pass_by_ref_mut = "deny" +needless_collect = "deny" +redundant_clone = "deny" +set_contains_or_insert = "deny" +significant_drop_in_scrutinee = "deny" +print_stdout = "deny" +print_stderr = "deny" + +# Expected/Allowed +cargo_common_metadata = "allow" +cast_precision_loss = "allow" +multiple_crate_versions = "allow" +single_call_fn = "allow" +unreadable_literal = "allow" +cast_lossless = "allow" +cast_sign_loss = "allow" +float_cmp = "allow" +cast_possible_truncation = "allow" +cast_possible_wrap = "allow" +missing_panics_doc = "allow" +missing_errors_doc = "allow" +module_name_repetitions = "allow" +struct_excessive_bools = "allow" + [workspace.package] version = "0.1.0-dev+1.21.11" edition = "2024" @@ -108,7 +152,7 @@ take_mut = "0.2.2" temp-dir = "0.1.16" thread_local = "1.1.9" time = "0.3" -arc-swap = "1.7" +arc-swap = "1.8" tokio-util = "0.7.18" toml = "0.9" ureq = "3.1.4" diff --git a/pumpkin-api-macros/Cargo.toml b/pumpkin-api-macros/Cargo.toml index a09e33762..d061c4945 100644 --- a/pumpkin-api-macros/Cargo.toml +++ b/pumpkin-api-macros/Cargo.toml @@ -12,3 +12,6 @@ syn .workspace = true quote.workspace = true proc-macro2.workspace = true proc-macro-error2.workspace = true + +[lints] +workspace = true diff --git a/pumpkin-config/Cargo.toml b/pumpkin-config/Cargo.toml index 8491369f2..c060ab2ab 100644 --- a/pumpkin-config/Cargo.toml +++ b/pumpkin-config/Cargo.toml @@ -15,3 +15,6 @@ toml.workspace = true [features] # Adds helper to change the config at runtime test_helper = [] + +[lints] +workspace = true diff --git a/pumpkin-config/src/chunk.rs b/pumpkin-config/src/chunk.rs index 57971c3e0..9e7b8d587 100644 --- a/pumpkin-config/src/chunk.rs +++ b/pumpkin-config/src/chunk.rs @@ -13,7 +13,7 @@ pub enum ChunkConfig { impl Default for ChunkConfig { fn default() -> Self { - Self::Anvil(Default::default()) + Self::Anvil(AnvilChunkConfig::default()) } } @@ -41,9 +41,9 @@ impl Default for ChunkCompression { #[derive(Deserialize, Serialize, Clone, Copy)] pub enum Compression { - /// GZip Compression + /// `GZip` Compression GZip, - /// ZLib Compression + /// `ZLib` Compression ZLib, /// LZ4 Compression (since 24w04a) LZ4, diff --git a/pumpkin-config/src/lib.rs b/pumpkin-config/src/lib.rs index a627f4fbb..12b92a49a 100644 --- a/pumpkin-config/src/lib.rs +++ b/pumpkin-config/src/lib.rs @@ -149,12 +149,16 @@ impl Default for BasicConfiguration { } impl BasicConfiguration { + #[must_use] pub fn get_world_path(&self) -> PathBuf { PathBuf::from(&self.default_level_name) } } pub trait LoadConfiguration { + #[must_use] + // Logger is may not ready + #[expect(clippy::print_stdout)] fn load(config_dir: &Path) -> Self where Self: Sized + Default + Serialize + DeserializeOwned, @@ -166,14 +170,15 @@ pub trait LoadConfiguration { let path = config_dir.join(Self::get_path()); let config = if path.exists() { - let file_content = fs::read_to_string(&path) - .unwrap_or_else(|_| panic!("Couldn't read configuration file at {:?}", &path)); + let file_content = fs::read_to_string(&path).unwrap_or_else(|_| { + panic!("Couldn't read configuration file at {}", path.display()) + }); let parsed_toml_value: toml::Value = toml::from_str(&file_content) .unwrap_or_else(|err| { panic!( - "Couldn't parse TOML at {:?}. Reason: {}. This is probably caused by invalid TOML syntax", - &path, err + "Couldn't parse TOML at {}. Reason: {}. This is probably caused by invalid TOML syntax", + path.display(), err ) }); @@ -186,8 +191,8 @@ pub trait LoadConfiguration { ); if let Err(err) = fs::write(&path, toml::to_string(&merged_config).unwrap()) { log::warn!( - "Couldn't write merged config to {:?}. Reason: {}", - &path, + "Couldn't write merged config to {}. Reason: {}", + path.display(), err ); } @@ -200,7 +205,7 @@ pub trait LoadConfiguration { if let Err(err) = fs::write(&path, toml::to_string(&content).unwrap()) { log::warn!( "Couldn't write default config to {:?}. Reason: {}", - &path, + path.display(), err ); } @@ -212,6 +217,7 @@ pub trait LoadConfiguration { config } + #[must_use] fn merge_with_default_toml(parsed_toml: toml::Value) -> (Self, bool) where Self: Sized + Default + Serialize + DeserializeOwned, @@ -221,8 +227,7 @@ pub trait LoadConfiguration { let default_toml_value = toml::Value::try_from(default_config).expect("Failed to parse default config"); - let (merged_value, changed) = - Self::merge_toml_values(default_toml_value, parsed_toml.clone()); + let (merged_value, changed) = Self::merge_toml_values(default_toml_value, parsed_toml); let config = merged_value .try_into() @@ -231,6 +236,7 @@ pub trait LoadConfiguration { (config, changed) } + #[must_use] fn merge_toml_values(base: toml::Value, overlay: toml::Value) -> (toml::Value, bool) { match (base, overlay) { (toml::Value::Table(mut base_table), toml::Value::Table(overlay_table)) => { @@ -272,7 +278,7 @@ impl LoadConfiguration for AdvancedConfiguration { } fn validate(&self) { - self.resource_pack.validate() + self.resource_pack.validate(); } } @@ -297,13 +303,13 @@ impl LoadConfiguration for BasicConfiguration { assert!( self.encryption, "When online mode is enabled, encryption must be enabled" - ) + ); } if self.allow_chat_reports { assert!( self.online_mode, "When allow_chat_reports is enabled, online_mode must be enabled" - ) + ); } } } diff --git a/pumpkin-config/src/networking/auth.rs b/pumpkin-config/src/networking/auth.rs index 3119b70a7..51c1c4e45 100644 --- a/pumpkin-config/src/networking/auth.rs +++ b/pumpkin-config/src/networking/auth.rs @@ -24,8 +24,8 @@ impl Default for AuthenticationConfig { Self { enabled: true, prevent_proxy_connections: false, - player_profile: Default::default(), - textures: Default::default(), + player_profile: PlayerProfileConfig::default(), + textures: TextureConfig::default(), url: None, prevent_proxy_connection_auth_url: None, services_url: None, @@ -75,7 +75,7 @@ impl Default for TextureConfig { enabled: true, allowed_url_schemes: vec!["http".into(), "https".into()], allowed_url_domains: vec![".minecraft.net".into(), ".mojang.com".into()], - types: Default::default(), + types: TextureTypes::default(), } } } diff --git a/pumpkin-config/src/networking/compression.rs b/pumpkin-config/src/networking/compression.rs index afda463b4..729918361 100644 --- a/pumpkin-config/src/networking/compression.rs +++ b/pumpkin-config/src/networking/compression.rs @@ -14,7 +14,7 @@ impl Default for CompressionConfig { fn default() -> Self { Self { enabled: true, - info: Default::default(), + info: CompressionInfo::default(), } } } diff --git a/pumpkin-config/src/networking/query.rs b/pumpkin-config/src/networking/query.rs index 9ef99f788..e925ffb8e 100644 --- a/pumpkin-config/src/networking/query.rs +++ b/pumpkin-config/src/networking/query.rs @@ -13,7 +13,7 @@ impl Default for QueryConfig { fn default() -> Self { Self { enabled: true, - address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 25565), + address: SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 25565), } } } diff --git a/pumpkin-config/src/networking/rcon.rs b/pumpkin-config/src/networking/rcon.rs index 43e13007c..51360a2b6 100644 --- a/pumpkin-config/src/networking/rcon.rs +++ b/pumpkin-config/src/networking/rcon.rs @@ -21,10 +21,10 @@ impl Default for RCONConfig { fn default() -> Self { Self { enabled: false, - address: SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 25575), - password: "".to_string(), + address: SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 25575), + password: String::new(), max_connections: 0, - logging: Default::default(), + logging: RCONLogging::default(), } } } diff --git a/pumpkin-config/src/op.rs b/pumpkin-config/src/op.rs index f0de992a1..5e60c61d0 100644 --- a/pumpkin-config/src/op.rs +++ b/pumpkin-config/src/op.rs @@ -11,6 +11,7 @@ pub struct Op { } impl Op { + #[must_use] pub fn new( uuid: Uuid, name: String, diff --git a/pumpkin-config/src/resource_pack.rs b/pumpkin-config/src/resource_pack.rs index 156fc97a4..d0676f1eb 100644 --- a/pumpkin-config/src/resource_pack.rs +++ b/pumpkin-config/src/resource_pack.rs @@ -30,6 +30,6 @@ impl ResourcePackConfig { assert!( hash_len == 40, "Resource pack SHA1 hash is the wrong length (should be 40, is {hash_len})" - ) + ); } } diff --git a/pumpkin-config/src/server_links.rs b/pumpkin-config/src/server_links.rs index cb8a9b3a4..a75780d32 100644 --- a/pumpkin-config/src/server_links.rs +++ b/pumpkin-config/src/server_links.rs @@ -22,15 +22,15 @@ impl Default for ServerLinksConfig { Self { enabled: true, bug_report: "https://github.com/Pumpkin-MC/Pumpkin/issues".to_string(), - support: "".to_string(), - status: "".to_string(), - feedback: "".to_string(), - community: "".to_string(), - website: "".to_string(), - forums: "".to_string(), - news: "".to_string(), - announcements: "".to_string(), - custom: Default::default(), + support: String::new(), + status: String::new(), + feedback: String::new(), + community: String::new(), + website: String::new(), + forums: String::new(), + news: String::new(), + announcements: String::new(), + custom: HashMap::default(), } } } diff --git a/pumpkin-data/Cargo.toml b/pumpkin-data/Cargo.toml index 0d70d8e6b..fd12bafda 100644 --- a/pumpkin-data/Cargo.toml +++ b/pumpkin-data/Cargo.toml @@ -36,3 +36,7 @@ criterion.workspace = true [[bench]] name = "has_random_ticks" harness = false + +# Generated files generate a lot of warns +# [lints] +# workspace = true \ No newline at end of file diff --git a/pumpkin-data/build/biome.rs b/pumpkin-data/build/biome.rs index e04e9a9bf..2b54c1076 100644 --- a/pumpkin-data/build/biome.rs +++ b/pumpkin-data/build/biome.rs @@ -111,7 +111,7 @@ enum BiomeTree { Branch { parameters: [ParameterRange; 7], #[serde(rename = "subTree")] - nodes: Box<[BiomeTree]>, + nodes: Box<[Self]>, }, } @@ -126,7 +126,7 @@ impl BiomeTree { .unwrap() .to_shouty_snake_case() ); - let parameters = parameters.map(|range| range.into_token_stream()); + let parameters = parameters.map(ParameterRange::into_token_stream); quote! { BiomeTree::Leaf { parameters: [#(#parameters),*], @@ -137,9 +137,9 @@ impl BiomeTree { Self::Branch { parameters, nodes } => { let nodes = nodes .into_iter() - .map(|node| node.into_token_stream()) + .map(Self::into_token_stream) .collect::>(); - let parameters = parameters.map(|range| range.into_token_stream()); + let parameters = parameters.map(ParameterRange::into_token_stream); quote! { BiomeTree::Branch { parameters: [#(#parameters),*], @@ -172,7 +172,7 @@ pub(crate) fn build() -> TokenStream { let mut name_to_type = TokenStream::new(); let mut id_to_type = TokenStream::new(); - for (name, biome) in biomes.into_iter() { + for (name, biome) in biomes { // let full_name = format!("minecraft:{name}"); let format_name = format_ident!("{}", name.to_shouty_snake_case()); let has_precipitation = biome.has_precipitation; @@ -190,44 +190,44 @@ pub(crate) fn build() -> TokenStream { .spawners .monster .iter() - .map(|s| s.to_tokens()) + .map(Spawner::to_tokens) .collect(); let ambient: Vec<_> = biome .spawners .ambient .iter() - .map(|s| s.to_tokens()) + .map(Spawner::to_tokens) .collect(); let axolotls: Vec<_> = biome .spawners .axolotls .iter() - .map(|s| s.to_tokens()) + .map(Spawner::to_tokens) .collect(); let creature: Vec<_> = biome .spawners .creature .iter() - .map(|s| s.to_tokens()) + .map(Spawner::to_tokens) .collect(); - let misc: Vec<_> = biome.spawners.misc.iter().map(|s| s.to_tokens()).collect(); + let misc: Vec<_> = biome.spawners.misc.iter().map(Spawner::to_tokens).collect(); let underground_water_creature: Vec<_> = biome .spawners .underground_water_creature .iter() - .map(|s| s.to_tokens()) + .map(Spawner::to_tokens) .collect(); let water_ambient: Vec<_> = biome .spawners .water_ambient .iter() - .map(|s| s.to_tokens()) + .map(Spawner::to_tokens) .collect(); let water_creature: Vec<_> = biome .spawners .water_creature .iter() - .map(|s| s.to_tokens()) + .map(Spawner::to_tokens) .collect(); let spawners = quote! { diff --git a/pumpkin-data/build/bitsets.rs b/pumpkin-data/build/bitsets.rs index 047c61069..cc1cdaff8 100644 --- a/pumpkin-data/build/bitsets.rs +++ b/pumpkin-data/build/bitsets.rs @@ -17,7 +17,7 @@ pub fn gen_u16_bitset(name: &str, ids: &[u16]) -> Bitset { let mut bitset = vec![0u64; words]; for &id in ids { let index = (id as usize) >> 6; - let bit = (id as u32) & 63; + let bit = u32::from(id) & 63; bitset[index] |= 1u64 << bit; } let name_uppercase = name.to_uppercase(); diff --git a/pumpkin-data/build/block.rs b/pumpkin-data/build/block.rs index 21b704713..86da5d580 100644 --- a/pumpkin-data/build/block.rs +++ b/pumpkin-data/build/block.rs @@ -418,11 +418,11 @@ pub enum PistonBehavior { impl PistonBehavior { fn to_tokens(&self) -> TokenStream { match self { - PistonBehavior::Normal => quote! { PistonBehavior::Normal }, - PistonBehavior::Destroy => quote! { PistonBehavior::Destroy }, - PistonBehavior::Block => quote! { PistonBehavior::Block }, - PistonBehavior::Ignore => quote! { PistonBehavior::Ignore }, - PistonBehavior::PushOnly => quote! { PistonBehavior::PushOnly }, + Self::Normal => quote! { PistonBehavior::Normal }, + Self::Destroy => quote! { PistonBehavior::Destroy }, + Self::Block => quote! { PistonBehavior::Block }, + Self::Ignore => quote! { PistonBehavior::Ignore }, + Self::PushOnly => quote! { PistonBehavior::PushOnly }, } } } @@ -447,20 +447,17 @@ impl BlockState { let instrument = format_ident!("{}", self.instrument.to_upper_camel_case()); let luminance = LitInt::new(&self.luminance.to_string(), Span::call_site()); let hardness = self.hardness; - let opacity = match self.opacity { - Some(opacity) => { - let opacity = LitInt::new(&opacity.to_string(), Span::call_site()); - quote! { #opacity } - } - None => quote! { 0 }, + let opacity = if let Some(opacity) = self.opacity { + let opacity = LitInt::new(&opacity.to_string(), Span::call_site()); + quote! { #opacity } + } else { + quote! { 0 } }; - let block_entity_type = match self.block_entity_type { - Some(block_entity_type) => { - let block_entity_type = - LitInt::new(&block_entity_type.to_string(), Span::call_site()); - quote! { #block_entity_type } - } - None => quote! { u16::MAX }, + let block_entity_type = if let Some(block_entity_type) = self.block_entity_type { + let block_entity_type = LitInt::new(&block_entity_type.to_string(), Span::call_site()); + quote! { #block_entity_type } + } else { + quote! { u16::MAX } }; let collision_shapes = self @@ -522,21 +519,19 @@ impl ToTokens for Block { let slipperiness = &self.slipperiness; let velocity_multiplier = &self.velocity_multiplier; let jump_velocity_multiplier = &self.jump_velocity_multiplier; - let experience = match &self.experience { - Some(exp) => { - let exp_tokens = exp.to_token_stream(); - quote! { Some(#exp_tokens) } - } - None => quote! { None }, + let experience = if let Some(exp) = &self.experience { + let exp_tokens = exp.to_token_stream(); + quote! { Some(#exp_tokens) } + } else { + quote! { None } }; // Generate state tokens - let states = self.states.iter().map(|state| state.to_tokens()); - let loot_table = match &self.loot_table { - Some(table) => { - let table_tokens = table.to_token_stream(); - quote! { Some(#table_tokens) } - } - None => quote! { None }, + let states = self.states.iter().map(BlockState::to_tokens); + let loot_table = if let Some(table) = &self.loot_table { + let table_tokens = table.to_token_stream(); + quote! { Some(#table_tokens) } + } else { + quote! { None } }; let default_state_ref: &BlockState = self @@ -547,12 +542,11 @@ impl ToTokens for Block { let mut default_state = default_state_ref.clone(); default_state.id = default_state_ref.id; let default_state = default_state.to_tokens(); - let flammable = match &self.flammable { - Some(flammable) => { - let flammable_tokens = flammable.to_token_stream(); - quote! { Some(#flammable_tokens) } - } - None => quote! { None }, + let flammable = if let Some(flammable) = &self.flammable { + let flammable_tokens = flammable.to_token_stream(); + quote! { Some(#flammable_tokens) } + } else { + quote! { None } }; tokens.extend(quote! { Block { @@ -800,10 +794,12 @@ pub(crate) fn build() -> TokenStream { .find(|(_, be_props)| { java_props_for_this_state .iter() - .all(|(k, v)| be_props.get(k).map(|be_v| be_v == v).unwrap_or(false)) + .all(|(k, v)| be_props.get(k).is_some_and(|be_v| be_v == v)) }) - .map(|(id, _)| *id) - .unwrap_or_else(|| be_variants.first().map(|(id, _)| *id).unwrap_or(1)); + .map_or_else( + || be_variants.first().map_or(1, |(id, _)| *id), + |(id, _)| *id, + ); } block_state_to_bedrock.push((state.id, matched_be_id)); @@ -861,12 +857,16 @@ pub(crate) fn build() -> TokenStream { let shapes = blocks_assets .shapes .iter() - .map(|shape| shape.to_token_stream()); + .map(quote::ToTokens::to_token_stream); let air_state_ids = quote! { #(#air_states)|* }; - let block_props = block_properties.iter().map(|prop| prop.to_token_stream()); - let properties = property_enums.values().map(|prop| prop.to_token_stream()); + let block_props = block_properties + .iter() + .map(quote::ToTokens::to_token_stream); + let properties = property_enums + .values() + .map(quote::ToTokens::to_token_stream); let block_entity_types = blocks_assets .block_entity_types @@ -1181,11 +1181,7 @@ fn get_be_data_from_nbt( let read_byte_safe = |reader: &mut R| -> Option { let mut buf = [0; 1]; - if reader.read_exact(&mut buf).is_ok() { - Some(buf[0]) - } else { - None - } + reader.read_exact(&mut buf).is_ok().then(|| buf[0]) }; while let Some(tag_id) = read_byte_safe(reader) { @@ -1234,7 +1230,7 @@ fn get_be_data_from_nbt( } 3 => read_varint(reader).to_string(), 8 => read_nbt_string(reader), - _ => panic!("Unknown property type {} for key {}", prop_type, prop_key), + _ => panic!("Unknown property type {prop_type} for key {prop_key}"), }; properties.insert(prop_key, prop_val); @@ -1242,7 +1238,7 @@ fn get_be_data_from_nbt( "version" => { read_varint(reader); } - _ => panic!("Unexpected root field: {}", field_name), + _ => panic!("Unexpected root field: {field_name}"), } } diff --git a/pumpkin-data/build/build.rs b/pumpkin-data/build/build.rs index e723698b0..bfdc1acdb 100644 --- a/pumpkin-data/build/build.rs +++ b/pumpkin-data/build/build.rs @@ -55,7 +55,7 @@ pub const OUT_DIR: &str = "src/generated"; pub fn main() { if let Err(e) = fs::create_dir_all(OUT_DIR) { - eprintln!("Failed to create output directory {}: {}", OUT_DIR, e); + eprintln!("Failed to create output directory {OUT_DIR}: {e}"); } type BuilderFn = fn() -> TokenStream; @@ -115,6 +115,7 @@ pub fn main() { }); } +#[must_use] pub fn array_to_tokenstream(array: &[String]) -> TokenStream { let variants = array.iter().map(|item| { let name = format_ident!("{}", item.to_pascal_case()); diff --git a/pumpkin-data/build/chunk_status.rs b/pumpkin-data/build/chunk_status.rs index 106d3fe0f..11c7aebc3 100644 --- a/pumpkin-data/build/chunk_status.rs +++ b/pumpkin-data/build/chunk_status.rs @@ -13,7 +13,7 @@ pub(crate) fn build() -> TokenStream { let variants: Vec = chunk_status .into_iter() .map(|status| { - let full_name = format!("minecraft:{}", status); + let full_name = format!("minecraft:{status}"); let name = format_ident!("{}", status.to_pascal_case()); quote! { diff --git a/pumpkin-data/build/damage_type.rs b/pumpkin-data/build/damage_type.rs index 2b81983d3..967e9123e 100644 --- a/pumpkin-data/build/damage_type.rs +++ b/pumpkin-data/build/damage_type.rs @@ -66,20 +66,18 @@ pub(crate) fn build() -> TokenStream { }); let data = &entry.components; - let death_message_type = match &data.death_message_type { - Some(msg) => { - let msg_ident = Ident::new(&format!("{msg:?}"), proc_macro2::Span::call_site()); - quote! { DeathMessageType::#msg_ident } - } - None => quote! { DeathMessageType::Default }, + let death_message_type = if let Some(msg) = &data.death_message_type { + let msg_ident = Ident::new(&format!("{msg:?}"), proc_macro2::Span::call_site()); + quote! { DeathMessageType::#msg_ident } + } else { + quote! { DeathMessageType::Default } }; - let effects = match &data.effects { - Some(msg) => { - let msg_ident = Ident::new(&format!("{msg:?}"), proc_macro2::Span::call_site()); - quote! { Some(DamageEffects::#msg_ident) } - } - None => quote! { None }, + let effects = if let Some(msg) = &data.effects { + let msg_ident = Ident::new(&format!("{msg:?}"), proc_macro2::Span::call_site()); + quote! { Some(DamageEffects::#msg_ident) } + } else { + quote! { None } }; let exhaustion = data.exhaustion; diff --git a/pumpkin-data/build/data_component.rs b/pumpkin-data/build/data_component.rs index 7d765c80e..0bc9ac842 100644 --- a/pumpkin-data/build/data_component.rs +++ b/pumpkin-data/build/data_component.rs @@ -22,7 +22,7 @@ pub(crate) fn build() -> TokenStream { let strip_name = raw_name .strip_prefix("minecraft:") .unwrap() - .replace("/", "_"); + .replace('/', "_"); let pascal_case = format_ident!("{}", strip_name.to_pascal_case()); // Enum variant diff --git a/pumpkin-data/build/dimension.rs b/pumpkin-data/build/dimension.rs index 6a1c778fe..e68cdfcff 100644 --- a/pumpkin-data/build/dimension.rs +++ b/pumpkin-data/build/dimension.rs @@ -60,9 +60,10 @@ pub(crate) fn build() -> TokenStream { .to_shouty_snake_case() ); - let fixed_time = match dim.fixed_time { - Some(t) => quote! { Some(#t) }, - None => quote! { None }, + let fixed_time = if let Some(t) = dim.fixed_time { + quote! { Some(#t) } + } else { + quote! { None } }; let ambient_light = dim.ambient_light; @@ -77,7 +78,7 @@ pub(crate) fn build() -> TokenStream { let minecraft_name = if name.contains(':') { name.clone() } else { - format!("minecraft:{}", name) + format!("minecraft:{name}") }; variants.extend(quote! { diff --git a/pumpkin-data/build/effect.rs b/pumpkin-data/build/effect.rs index 9b01f8c30..26ed69f54 100644 --- a/pumpkin-data/build/effect.rs +++ b/pumpkin-data/build/effect.rs @@ -51,9 +51,9 @@ impl Modifiers { impl MobEffectCategory { pub fn to_tokens(&self) -> TokenStream { match self { - MobEffectCategory::BENEFICIAL => quote! { MobEffectCategory::Beneficial }, - MobEffectCategory::HARMFUL => quote! { MobEffectCategory::Harmful }, - MobEffectCategory::NEUTRAL => quote! { MobEffectCategory::Neutral }, + Self::BENEFICIAL => quote! { MobEffectCategory::Beneficial }, + Self::HARMFUL => quote! { MobEffectCategory::Harmful }, + Self::NEUTRAL => quote! { MobEffectCategory::Neutral }, } } } @@ -69,14 +69,14 @@ pub(crate) fn build() -> TokenStream { let mut name_to_type = TokenStream::new(); let mut minecraft_name_to_type = TokenStream::new(); - for (name, effect) in effects.into_iter() { + for (name, effect) in effects { let format_name = format_ident!("{}", name.to_shouty_snake_case()); let id = effect.id; let color = effect.color; let translation_key = effect.translation_key; let category = effect.category.to_tokens(); let slots = effect.attribute_modifiers; - let slots = slots.into_iter().map(|slot| slot.get_tokens()); + let slots = slots.into_iter().map(Modifiers::get_tokens); let minecraft_name = "minecraft:".to_string() + &name; variants.extend([quote! { diff --git a/pumpkin-data/build/enchantments.rs b/pumpkin-data/build/enchantments.rs index 1ee26d9de..d59a18ea3 100644 --- a/pumpkin-data/build/enchantments.rs +++ b/pumpkin-data/build/enchantments.rs @@ -37,17 +37,17 @@ pub enum AttributeModifierSlot { impl AttributeModifierSlot { pub fn to_tokens(&self) -> TokenStream { match self { - AttributeModifierSlot::Any => quote! { AttributeModifierSlot::Any }, - AttributeModifierSlot::MainHand => quote! { AttributeModifierSlot::MainHand }, - AttributeModifierSlot::OffHand => quote! { AttributeModifierSlot::OffHand }, - AttributeModifierSlot::Hand => quote! { AttributeModifierSlot::Hand }, - AttributeModifierSlot::Feet => quote! { AttributeModifierSlot::Feet }, - AttributeModifierSlot::Legs => quote! { AttributeModifierSlot::Legs }, - AttributeModifierSlot::Chest => quote! { AttributeModifierSlot::Chest }, - AttributeModifierSlot::Head => quote! { AttributeModifierSlot::Head }, - AttributeModifierSlot::Armor => quote! { AttributeModifierSlot::Armor }, - AttributeModifierSlot::Body => quote! { AttributeModifierSlot::Body }, - AttributeModifierSlot::Saddle => quote! { AttributeModifierSlot::Saddle }, + Self::Any => quote! { AttributeModifierSlot::Any }, + Self::MainHand => quote! { AttributeModifierSlot::MainHand }, + Self::OffHand => quote! { AttributeModifierSlot::OffHand }, + Self::Hand => quote! { AttributeModifierSlot::Hand }, + Self::Feet => quote! { AttributeModifierSlot::Feet }, + Self::Legs => quote! { AttributeModifierSlot::Legs }, + Self::Chest => quote! { AttributeModifierSlot::Chest }, + Self::Head => quote! { AttributeModifierSlot::Head }, + Self::Armor => quote! { AttributeModifierSlot::Armor }, + Self::Body => quote! { AttributeModifierSlot::Body }, + Self::Saddle => quote! { AttributeModifierSlot::Saddle }, } } } @@ -63,7 +63,7 @@ pub(crate) fn build() -> TokenStream { let mut name_to_type = TokenStream::new(); let mut id_to_type = TokenStream::new(); - for (name, enchantment) in enchantments.into_iter() { + for (name, enchantment) in enchantments { let id = enchantment.id; let raw_name = name.strip_prefix("minecraft:").unwrap(); let format_name = format_ident!("{}", raw_name.to_shouty_snake_case()); @@ -74,13 +74,12 @@ pub(crate) fn build() -> TokenStream { .supported_items .strip_prefix("#") .unwrap() - .replace(":", "_") - .replace("/", "_") + .replace([':', '/'], "_") .to_uppercase() ); let max_level = enchantment.max_level; let slots = enchantment.slots; - let slots = slots.iter().map(|slot| slot.to_tokens()); + let slots = slots.iter().map(AttributeModifierSlot::to_tokens); let Translate { translate, with: _ } = &enchantment.description.0.content else { panic!() }; @@ -92,8 +91,7 @@ pub(crate) fn build() -> TokenStream { exclusive_set .strip_prefix("#") .unwrap() - .replace(":", "_") - .replace("/", "_") + .replace([':', '/'], "_") .to_uppercase() ); variants.extend([quote! { diff --git a/pumpkin-data/build/entity_type.rs b/pumpkin-data/build/entity_type.rs index 0588f5d3a..bdb9747cd 100644 --- a/pumpkin-data/build/entity_type.rs +++ b/pumpkin-data/build/entity_type.rs @@ -63,14 +63,16 @@ impl ToTokens for NamedEntityType<'_> { let entity = self.1; let id = LitInt::new(&entity.id.to_string(), proc_macro2::Span::call_site()); - let max_health = match entity.max_health { - Some(mh) => quote! { Some(#mh) }, - None => quote! { None }, + let max_health = if let Some(mh) = entity.max_health { + quote! { Some(#mh) } + } else { + quote! { None } }; - let attackable = match entity.attackable { - Some(a) => quote! { Some(#a) }, - None => quote! { None }, + let attackable = if let Some(a) = entity.attackable { + quote! { Some(#a) } + } else { + quote! { None } }; let spawn_restriction_location = match entity.spawn_restriction.location { @@ -111,12 +113,14 @@ impl ToTokens for NamedEntityType<'_> { let summonable = entity.summonable; let fire_immune = entity.fire_immune; let eye_height = entity.eye_height; - if entity.mob.is_none() && name != "player" { - panic!("missing field 'mob', entity name {name}"); - } - if entity.limit_per_chunk.is_none() && name != "player" { - panic!("missing field 'mob', entity name {name}"); - } + assert!( + !(entity.mob.is_none() && name != "player"), + "missing field 'mob', entity name {name}" + ); + assert!( + !(entity.limit_per_chunk.is_none() && name != "player"), + "missing field 'mob', entity name {name}" + ); let mob = entity.mob.unwrap_or(false); let limit_per_chunk = entity.limit_per_chunk.unwrap_or(0); let can_spawn_far_from_player = entity.can_spawn_far_from_player; @@ -124,12 +128,11 @@ impl ToTokens for NamedEntityType<'_> { let dimension0 = entity.dimension[0]; let dimension1 = entity.dimension[1]; - let loot_table = match &entity.loot_table { - Some(table) => { - let table_tokens = table.to_token_stream(); - quote! { Some(#table_tokens) } - } - None => quote! { None }, + let loot_table = if let Some(table) = &entity.loot_table { + let table_tokens = table.to_token_stream(); + quote! { Some(#table_tokens) } + } else { + quote! { None } }; tokens.extend(quote! { @@ -165,7 +168,7 @@ pub(crate) fn build() -> TokenStream { let mut type_from_raw_id_arms = TokenStream::new(); let mut type_from_name = TokenStream::new(); - for (name, entity) in json.iter() { + for (name, entity) in &json { let id = entity.id as u8; let id_lit = LitInt::new(&id.to_string(), proc_macro2::Span::call_site()); let upper_name = format_ident!("{}", name.to_uppercase()); diff --git a/pumpkin-data/build/fluid.rs b/pumpkin-data/build/fluid.rs index 234568651..012d5b839 100644 --- a/pumpkin-data/build/fluid.rs +++ b/pumpkin-data/build/fluid.rs @@ -57,7 +57,7 @@ impl ToTokens for PropertyStruct { let values_index = (0..self.values.len() as u16).collect::>(); let ident_values = self.values.iter().map(|value| { - let value_str = if value.chars().all(|c| c.is_numeric()) { + let value_str = if value.chars().all(char::is_numeric) { format!("L{value}") } else { value.clone() @@ -69,7 +69,7 @@ impl ToTokens for PropertyStruct { let values_3 = ident_values.clone(); let from_values = self.values.iter().map(|value| { - let value_str = if value.chars().all(|c| c.is_numeric()) { + let value_str = if value.chars().all(char::is_numeric) { format!("L{value}") } else { value.clone() @@ -80,7 +80,7 @@ impl ToTokens for PropertyStruct { } }); let to_values = self.values.iter().map(|value| { - let value_str = if value.chars().all(|c| c.is_numeric()) { + let value_str = if value.chars().all(char::is_numeric) { format!("L{value}") } else { value.clone() @@ -512,12 +512,13 @@ pub(crate) fn build() -> TokenStream { .entry(renamed_property.clone()) .or_insert_with(|| property.values.clone()); - if expected_values != &property.values { - panic!( - "Enum overlap for '{}' ({:?} vs {:?})", - property.name, &property.values, expected_values - ); - }; + assert!( + expected_values == &property.values, + "Enum overlap for '{}' ({:?} vs {:?})", + property.name, + &property.values, + expected_values + ); property_mapping.push(PropertyVariantMapping { original_name: property.name.clone(), @@ -591,8 +592,12 @@ pub(crate) fn build() -> TokenStream { }); } - let fluid_props = fluid_properties.iter().map(|prop| prop.to_token_stream()); - let properties = property_enums.values().map(|prop| prop.to_token_stream()); + let fluid_props = fluid_properties + .iter() + .map(quote::ToTokens::to_token_stream); + let properties = property_enums + .values() + .map(quote::ToTokens::to_token_stream); quote! { use std::hash::{Hash, Hasher}; diff --git a/pumpkin-data/build/item.rs b/pumpkin-data/build/item.rs index 6702ff4d5..c652ccc33 100644 --- a/pumpkin-data/build/item.rs +++ b/pumpkin-data/build/item.rs @@ -81,7 +81,7 @@ impl ToTokens for ItemComponents { damage: #damage_lit, }), }); - }; + } if let Some(md) = self.max_damage { let max_damage_lit = LitInt::new(&md.to_string(), Span::call_site()); @@ -90,7 +90,7 @@ impl ToTokens for ItemComponents { max_damage: #max_damage_lit, }), }); - }; + } if let Some(modifiers) = &self.attribute_modifiers { let modifier_code = modifiers.iter().map(|modifier| { @@ -122,7 +122,7 @@ impl ToTokens for ItemComponents { attribute_modifiers: Cow::Borrowed(&[#(#modifier_code),*]) }), }); - }; + } if let Some(tool) = &self.tool { let rules_code = tool.rules.iter().map(|rule| { @@ -138,10 +138,8 @@ impl ToTokens for ItemComponents { Blocks(Cow::Borrowed(&[&Block::#ident])) } } else if let TagType::Tag(str) = t { - let ident = format_ident!( - "{}", - str.replace(":", "_").replace("/", "_").to_uppercase() - ); + let ident = + format_ident!("{}", str.replace([':', '/'], "_").to_uppercase()); block_array = quote! { Tag(&tag::Block::#ident) } @@ -168,18 +166,16 @@ impl ToTokens for ItemComponents { } else { unreachable!(); } - let speed = match rule.speed { - Some(speed) => { - quote! { Some(#speed) } - } - None => quote! { None }, + let speed = if let Some(speed) = rule.speed { + quote! { Some(#speed) } + } else { + quote! { None } }; - let correct_for_drops = match rule.correct_for_drops { - Some(correct_for_drops) => { - let correct_for_drops = LitBool::new(correct_for_drops, Span::call_site()); - quote! { Some(#correct_for_drops) } - } - None => quote! { None }, + let correct_for_drops = if let Some(correct_for_drops) = rule.correct_for_drops { + let correct_for_drops = LitBool::new(correct_for_drops, Span::call_site()); + quote! { Some(#correct_for_drops) } + } else { + quote! { None } }; quote! { ToolRule { @@ -208,7 +204,7 @@ impl ToTokens for ItemComponents { damage_per_block: #damage_per_block, can_destroy_blocks_in_creative: #can_destroy_blocks_in_creative }), }); - }; + } if let Some(food) = &self.food { let nutrition = LitInt::new(&food.nutrition.to_string(), Span::call_site()); @@ -222,7 +218,7 @@ impl ToTokens for ItemComponents { saturation: #saturation, can_always_eat: #can_always_eat, }), }); - }; + } if let Some(consumable) = &self.consumable { let consume_seconds = LitFloat::new( @@ -233,15 +229,15 @@ impl ToTokens for ItemComponents { tokens.extend(quote! { (Consumable, &ConsumableImpl { consume_seconds: #consume_seconds, }), }); - }; + } if self.blocks_attacks.is_some() { tokens.extend(quote! { (BlocksAttacks, &BlocksAttacksImpl), }); - }; + } if self.death_protection.is_some() { tokens.extend(quote! { (DeathProtection, &DeathProtectionImpl), }); - }; + } if let Some(equippable) = &self.equippable { let slot = match equippable.slot.as_str() { @@ -298,7 +294,7 @@ impl ToTokens for ItemComponents { TagType::Tag(tag) => { let ident = format_ident!( "{}", - tag.replace(":", "_").replace("/", "_").to_uppercase() + tag.replace([':', '/'], "_").to_uppercase() ); quote! { EntityTypeOrTag::Tag(&crate::tag::EntityType::#ident) } } @@ -339,7 +335,7 @@ impl ToTokens for ItemComponents { can_be_sheared: #can_be_sheared, shearing_sound: #shearing_sound }), }); - }; + } } } diff --git a/pumpkin-data/build/loot.rs b/pumpkin-data/build/loot.rs index 9ed0b2888..e102e0209 100644 --- a/pumpkin-data/build/loot.rs +++ b/pumpkin-data/build/loot.rs @@ -17,16 +17,16 @@ pub struct LootTableStruct { impl ToTokens for LootTableStruct { fn to_tokens(&self, tokens: &mut TokenStream) { let loot_table_type = self.r#type.to_token_stream(); - let random_sequence = match &self.random_sequence { - Some(seq) => quote! { Some(#seq) }, - None => quote! { None }, + let random_sequence = if let Some(seq) = &self.random_sequence { + quote! { Some(#seq) } + } else { + quote! { None } }; - let pools = match &self.pools { - Some(pools) => { - let pool_tokens: Vec<_> = pools.iter().map(|pool| pool.to_token_stream()).collect(); - quote! { Some(&[#(#pool_tokens),*]) } - } - None => quote! { None }, + let pools = if let Some(pools) = &self.pools { + let pool_tokens: Vec<_> = pools.iter().map(quote::ToTokens::to_token_stream).collect(); + quote! { Some(&[#(#pool_tokens),*]) } + } else { + quote! { None } }; tokens.extend(quote! { @@ -53,23 +53,21 @@ impl ToTokens for LootPoolStruct { let entries_tokens: Vec<_> = self .entries .iter() - .map(|entry| entry.to_token_stream()) + .map(quote::ToTokens::to_token_stream) .collect(); let rolls = &self.rolls; let bonus_rolls = &self.bonus_rolls; - let conditions_tokens = match &self.conditions { - Some(conds) => { - let cond_tokens: Vec<_> = conds.iter().map(|c| c.to_token_stream()).collect(); - quote! { Some(&[#(#cond_tokens),*]) } - } - None => quote! { None }, + let conditions_tokens = if let Some(conds) = &self.conditions { + let cond_tokens: Vec<_> = conds.iter().map(quote::ToTokens::to_token_stream).collect(); + quote! { Some(&[#(#cond_tokens),*]) } + } else { + quote! { None } }; - let functions_tokens = match &self.functions { - Some(fns) => { - let cond_tokens: Vec<_> = fns.iter().map(|c| c.to_token_stream()).collect(); - quote! { Some(&[#(#cond_tokens),*]) } - } - None => quote! { None }, + let functions_tokens = if let Some(fns) = &self.functions { + let cond_tokens: Vec<_> = fns.iter().map(quote::ToTokens::to_token_stream).collect(); + quote! { Some(&[#(#cond_tokens),*]) } + } else { + quote! { None } }; tokens.extend(quote! { @@ -108,7 +106,7 @@ pub struct AlternativeEntryStruct { impl ToTokens for AlternativeEntryStruct { fn to_tokens(&self, tokens: &mut TokenStream) { - let children = self.children.iter().map(|entry| entry.to_token_stream()); + let children = self.children.iter().map(quote::ToTokens::to_token_stream); tokens.extend(quote! { AlternativeEntry { @@ -142,28 +140,28 @@ pub enum LootPoolEntryTypesStruct { impl ToTokens for LootPoolEntryTypesStruct { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - LootPoolEntryTypesStruct::Empty => { + Self::Empty => { tokens.extend(quote! { LootPoolEntryTypes::Empty }); } - LootPoolEntryTypesStruct::Item(item) => { + Self::Item(item) => { tokens.extend(quote! { LootPoolEntryTypes::Item(#item) }); } - LootPoolEntryTypesStruct::LootTable => { + Self::LootTable => { tokens.extend(quote! { LootPoolEntryTypes::LootTable }); } - LootPoolEntryTypesStruct::Dynamic => { + Self::Dynamic => { tokens.extend(quote! { LootPoolEntryTypes::Dynamic }); } - LootPoolEntryTypesStruct::Tag => { + Self::Tag => { tokens.extend(quote! { LootPoolEntryTypes::Tag }); } - LootPoolEntryTypesStruct::Alternatives(alt) => { + Self::Alternatives(alt) => { tokens.extend(quote! { LootPoolEntryTypes::Alternatives(#alt) }); } - LootPoolEntryTypesStruct::Sequence => { + Self::Sequence => { tokens.extend(quote! { LootPoolEntryTypes::Sequence }); } - LootPoolEntryTypesStruct::Group => { + Self::Group => { tokens.extend(quote! { LootPoolEntryTypes::Group }); } } @@ -219,35 +217,35 @@ pub enum LootConditionStruct { impl ToTokens for LootConditionStruct { fn to_tokens(&self, tokens: &mut TokenStream) { let name = match self { - LootConditionStruct::Inverted => quote! { LootCondition::Inverted }, - LootConditionStruct::AnyOf => quote! { LootCondition::AnyOf }, - LootConditionStruct::AllOf => quote! { LootCondition::AllOf }, - LootConditionStruct::RandomChance => quote! { LootCondition::RandomChance }, - LootConditionStruct::RandomChanceWithEnchantedBonus => { + Self::Inverted => quote! { LootCondition::Inverted }, + Self::AnyOf => quote! { LootCondition::AnyOf }, + Self::AllOf => quote! { LootCondition::AllOf }, + Self::RandomChance => quote! { LootCondition::RandomChance }, + Self::RandomChanceWithEnchantedBonus => { quote! { LootCondition::RandomChanceWithEnchantedBonus } } - LootConditionStruct::EntityProperties => quote! { LootCondition::EntityProperties }, - LootConditionStruct::KilledByPlayer => quote! { LootCondition::KilledByPlayer }, - LootConditionStruct::EntityScores => quote! { LootCondition::EntityScores }, - LootConditionStruct::BlockStateProperty { block, properties } => { + Self::EntityProperties => quote! { LootCondition::EntityProperties }, + Self::KilledByPlayer => quote! { LootCondition::KilledByPlayer }, + Self::EntityScores => quote! { LootCondition::EntityScores }, + Self::BlockStateProperty { block, properties } => { let properties: Vec<_> = properties .iter() .map(|(k, v)| quote! { (#k, #v) }) .collect(); quote! { LootCondition::BlockStateProperty { block: #block, properties: &[#(#properties),*] } } } - LootConditionStruct::MatchTool => quote! { LootCondition::MatchTool }, - LootConditionStruct::TableBonus => quote! { LootCondition::TableBonus }, - LootConditionStruct::SurvivesExplosion => quote! { LootCondition::SurvivesExplosion }, - LootConditionStruct::DamageSourceProperties => { + Self::MatchTool => quote! { LootCondition::MatchTool }, + Self::TableBonus => quote! { LootCondition::TableBonus }, + Self::SurvivesExplosion => quote! { LootCondition::SurvivesExplosion }, + Self::DamageSourceProperties => { quote! { LootCondition::DamageSourceProperties } } - LootConditionStruct::LocationCheck => quote! { LootCondition::LocationCheck }, - LootConditionStruct::WeatherCheck => quote! { LootCondition::WeatherCheck }, - LootConditionStruct::Reference => quote! { LootCondition::Reference }, - LootConditionStruct::TimeCheck => quote! { LootCondition::TimeCheck }, - LootConditionStruct::ValueCheck => quote! { LootCondition::ValueCheck }, - LootConditionStruct::EnchantmentActiveCheck => { + Self::LocationCheck => quote! { LootCondition::LocationCheck }, + Self::WeatherCheck => quote! { LootCondition::WeatherCheck }, + Self::Reference => quote! { LootCondition::Reference }, + Self::TimeCheck => quote! { LootCondition::TimeCheck }, + Self::ValueCheck => quote! { LootCondition::ValueCheck }, + Self::EnchantmentActiveCheck => { quote! { LootCondition::EnchantmentActiveCheck } } }; @@ -267,12 +265,11 @@ impl ToTokens for LootFunctionStruct { fn to_tokens(&self, tokens: &mut TokenStream) { let functions_tokens = &self.content.to_token_stream(); - let conditions_tokens = match &self.conditions { - Some(conds) => { - let cond_tokens: Vec<_> = conds.iter().map(|c| c.to_token_stream()).collect(); - quote! { Some(&[#(#cond_tokens),*]) } - } - None => quote! { None }, + let conditions_tokens = if let Some(conds) = &self.conditions { + let cond_tokens: Vec<_> = conds.iter().map(quote::ToTokens::to_token_stream).collect(); + quote! { Some(&[#(#cond_tokens),*]) } + } else { + quote! { None } }; tokens.extend(quote! { @@ -325,45 +322,46 @@ pub enum LootFunctionTypesStruct { impl ToTokens for LootFunctionTypesStruct { fn to_tokens(&self, tokens: &mut TokenStream) { let name = match self { - LootFunctionTypesStruct::SetCount { count, add } => { + Self::SetCount { count, add } => { let count = count.to_token_stream(); let add = add.unwrap_or(false); quote! { LootFunctionTypes::SetCount { count: #count, add: #add } } } - LootFunctionTypesStruct::SetOminousBottleAmplifier => { + Self::SetOminousBottleAmplifier => { quote! { LootFunctionTypes::SetOminousBottleAmplifier } } - LootFunctionTypesStruct::FurnaceSmelt => { + Self::FurnaceSmelt => { quote! { LootFunctionTypes::FurnaceSmelt } } - LootFunctionTypesStruct::SetPotion => { + Self::SetPotion => { quote! { LootFunctionTypes::SetPotion } } - LootFunctionTypesStruct::EnchantedCountIncrease => { + Self::EnchantedCountIncrease => { quote! { LootFunctionTypes::EnchantedCountIncrease } } - LootFunctionTypesStruct::LimitCount { limit } => { - let min = match limit.min { - Some(min) => quote! { Some(#min) }, - None => quote! { None }, + Self::LimitCount { limit } => { + let min = if let Some(min) = limit.min { + quote! { Some(#min) } + } else { + quote! { None } }; - let max = match limit.max { - Some(max) => quote! { Some(#max) }, - None => quote! { None }, + let max = if let Some(max) = limit.max { + quote! { Some(#max) } + } else { + quote! { None } }; quote! { LootFunctionTypes::LimitCount { min: #min, max: #max } } } - LootFunctionTypesStruct::ApplyBonus { + Self::ApplyBonus { enchantment, formula, parameters, } => { - let parameters = match parameters { - Some(params) => { - let params = params.to_token_stream(); - quote! { Some(#params) } - } - None => quote! { None }, + let parameters = if let Some(params) = parameters { + let params = params.to_token_stream(); + quote! { Some(#params) } + } else { + quote! { None } }; quote! { @@ -374,7 +372,7 @@ impl ToTokens for LootFunctionTypesStruct { } } } - LootFunctionTypesStruct::CopyComponents { source, include } => { + Self::CopyComponents { source, include } => { quote! { LootFunctionTypes::CopyComponents { source: #source, @@ -382,7 +380,7 @@ impl ToTokens for LootFunctionTypesStruct { } } } - LootFunctionTypesStruct::CopyState { block, properties } => { + Self::CopyState { block, properties } => { quote! { LootFunctionTypes::CopyState { block: #block, @@ -390,7 +388,7 @@ impl ToTokens for LootFunctionTypesStruct { } } } - LootFunctionTypesStruct::ExplosionDecay => { + Self::ExplosionDecay => { quote! { LootFunctionTypes::ExplosionDecay } } }; @@ -473,19 +471,17 @@ pub struct LootPoolEntryStruct { impl ToTokens for LootPoolEntryStruct { fn to_tokens(&self, tokens: &mut TokenStream) { let content = &self.content; - let conditions_tokens = match &self.conditions { - Some(conds) => { - let cond_tokens: Vec<_> = conds.iter().map(|c| c.to_token_stream()).collect(); - quote! { Some(&[#(#cond_tokens),*]) } - } - None => quote! { None }, + let conditions_tokens = if let Some(conds) = &self.conditions { + let cond_tokens: Vec<_> = conds.iter().map(quote::ToTokens::to_token_stream).collect(); + quote! { Some(&[#(#cond_tokens),*]) } + } else { + quote! { None } }; - let functions_tokens = match &self.functions { - Some(fns) => { - let cond_tokens: Vec<_> = fns.iter().map(|c| c.to_token_stream()).collect(); - quote! { Some(&[#(#cond_tokens),*]) } - } - None => quote! { None }, + let functions_tokens = if let Some(fns) = &self.functions { + let cond_tokens: Vec<_> = fns.iter().map(quote::ToTokens::to_token_stream).collect(); + quote! { Some(&[#(#cond_tokens),*]) } + } else { + quote! { None } }; tokens.extend(quote! { @@ -518,10 +514,10 @@ pub enum LootTableTypeStruct { impl ToTokens for LootTableTypeStruct { fn to_tokens(&self, tokens: &mut TokenStream) { let name = match self { - LootTableTypeStruct::Empty => quote! { LootTableType::Empty }, - LootTableTypeStruct::Entity => quote! { LootTableType::Entity }, - LootTableTypeStruct::Block => quote! { LootTableType::Block }, - LootTableTypeStruct::Chest => quote! { LootTableType::Chest }, + Self::Empty => quote! { LootTableType::Empty }, + Self::Entity => quote! { LootTableType::Entity }, + Self::Block => quote! { LootTableType::Block }, + Self::Chest => quote! { LootTableType::Chest }, }; tokens.extend(name); diff --git a/pumpkin-data/build/message_type.rs b/pumpkin-data/build/message_type.rs index 526ec34c4..b7adc22c3 100644 --- a/pumpkin-data/build/message_type.rs +++ b/pumpkin-data/build/message_type.rs @@ -32,7 +32,7 @@ pub(crate) fn build() -> TokenStream { .expect("Failed to parse message_type.json"); let mut variants = TokenStream::new(); - for (name, typee) in json.iter() { + for (name, typee) in &json { let i = typee.id as u8; let name = format_ident!("{}", name.to_uppercase()); variants.extend([quote! { diff --git a/pumpkin-data/build/noise_parameter.rs b/pumpkin-data/build/noise_parameter.rs index 5fb1c13ad..1440635e7 100644 --- a/pumpkin-data/build/noise_parameter.rs +++ b/pumpkin-data/build/noise_parameter.rs @@ -13,7 +13,7 @@ pub(crate) fn build() -> TokenStream { let mut variants = TokenStream::new(); let mut match_variants = TokenStream::new(); - for (name, parameter) in json.iter() { + for (name, parameter) in &json { let raw_name = format!("minecraft:{name}"); let simple_id = name; let name = format_ident!("{}", name.to_uppercase()); diff --git a/pumpkin-data/build/noise_router.rs b/pumpkin-data/build/noise_router.rs index 1e5918d60..fbdc6257f 100644 --- a/pumpkin-data/build/noise_router.rs +++ b/pumpkin-data/build/noise_router.rs @@ -87,7 +87,7 @@ enum SplineRepr { #[serde(rename(deserialize = "locationFunction"))] location_function: Box, locations: Box<[HashableF32]>, - values: Box<[SplineRepr]>, + values: Box<[Self]>, derivatives: Box<[HashableF32]>, }, #[serde(rename(deserialize = "fixed"))] @@ -459,7 +459,7 @@ enum DensityFunctionRepr { BlendAlpha, BlendOffset, BlendDensity { - input: Box, + input: Box, }, EndIslands, Noise { @@ -476,11 +476,11 @@ enum DensityFunctionRepr { }, ShiftedNoise { #[serde(rename(deserialize = "shiftX"))] - shift_x: Box, + shift_x: Box, #[serde(rename(deserialize = "shiftY"))] - shift_y: Box, + shift_y: Box, #[serde(rename(deserialize = "shiftZ"))] - shift_z: Box, + shift_z: Box, #[serde(flatten)] data: ShiftedNoiseData, }, @@ -490,7 +490,7 @@ enum DensityFunctionRepr { }, #[serde(rename(deserialize = "WeirdScaledSampler"))] WeirdScaled { - input: Box, + input: Box, #[serde(flatten)] data: WeirdScaledData, }, @@ -498,7 +498,7 @@ enum DensityFunctionRepr { #[serde(rename(deserialize = "Wrapping"))] Wrapper { #[serde(rename(deserialize = "wrapped"))] - input: Box, + input: Box, #[serde(rename(deserialize = "type"))] wrapper: WrapperType, }, @@ -513,34 +513,34 @@ enum DensityFunctionRepr { }, #[serde(rename(deserialize = "BinaryOperation"))] Binary { - argument1: Box, - argument2: Box, + argument1: Box, + argument2: Box, #[serde(flatten)] data: BinaryData, }, #[serde(rename(deserialize = "LinearOperation"))] Linear { - input: Box, + input: Box, #[serde(flatten)] data: LinearData, }, #[serde(rename(deserialize = "UnaryOperation"))] Unary { - input: Box, + input: Box, #[serde(flatten)] data: UnaryData, }, Clamp { - input: Box, + input: Box, #[serde(flatten)] data: ClampData, }, RangeChoice { - input: Box, + input: Box, #[serde(rename(deserialize = "whenInRange"))] - when_in_range: Box, + when_in_range: Box, #[serde(rename(deserialize = "whenOutOfRange"))] - when_out_range: Box, + when_out_range: Box, #[serde(flatten)] data: RangeChoiceData, }, @@ -720,8 +720,8 @@ impl DensityFunctionRepr { } } Self::ClampedYGradient { data } => { - let from_y = data.from_y as f64; - let to_y = data.to_y as f64; + let from_y = f64::from(data.from_y); + let to_y = f64::from(data.to_y); let from_value = &data.from_value; let to_value = &data.to_value; diff --git a/pumpkin-data/build/packet.rs b/pumpkin-data/build/packet.rs index 814dfb630..ecf240246 100644 --- a/pumpkin-data/build/packet.rs +++ b/pumpkin-data/build/packet.rs @@ -92,14 +92,14 @@ fn generate_mapped_consts(latest: &Packets, v7: &Packets, is_serverbound: bool) for (phase, packets) in latest_phases { for (name, id_11) in packets { - let sanitized = name.replace("/", "_").replace("-", "_").to_uppercase(); + let sanitized = name.replace(['/', '-'], "_").to_uppercase(); let const_name = format_ident!("{}_{}", phase.to_uppercase(), sanitized); // Check if the packet exists in 1.21.7 to get the alternate ID let id_7 = v7_phases .get(phase) .and_then(|p| p.get(name)) - .cloned() + .copied() .unwrap_or(-1); // Since serverbound/clientbound are modules, we reference the PacketId in the parent scope diff --git a/pumpkin-data/build/potion.rs b/pumpkin-data/build/potion.rs index ef8872768..a770379f0 100644 --- a/pumpkin-data/build/potion.rs +++ b/pumpkin-data/build/potion.rs @@ -59,11 +59,11 @@ pub(crate) fn build() -> TokenStream { let mut variants = TokenStream::new(); let mut name_to_type = TokenStream::new(); - for (name, potion) in potions.into_iter() { + for (name, potion) in potions { let format_name = format_ident!("{}", name.to_shouty_snake_case()); let id = potion.id; let slots = potion.effects; - let slots = slots.iter().map(|slot| slot.to_tokens()); + let slots = slots.iter().map(Effect::to_tokens); variants.extend([quote! { pub const #format_name: Self = Self { diff --git a/pumpkin-data/build/potion_brewing.rs b/pumpkin-data/build/potion_brewing.rs index 3c06c3695..cea29b4da 100644 --- a/pumpkin-data/build/potion_brewing.rs +++ b/pumpkin-data/build/potion_brewing.rs @@ -81,7 +81,7 @@ pub(crate) fn build() -> TokenStream { let item_recipes_tokens: Vec = json .item_recipes .into_iter() - .map(|recipe| recipe.get_tokens_item()) + .map(Recipes::get_tokens_item) .collect(); let item_len = item_recipes_tokens.len(); @@ -89,7 +89,7 @@ pub(crate) fn build() -> TokenStream { let potion_recipes_tokens: Vec = json .potion_recipes .into_iter() - .map(|recipe| recipe.get_tokens_potion()) + .map(Recipes::get_tokens_potion) .collect(); let potion_len = potion_recipes_tokens.len(); diff --git a/pumpkin-data/build/recipes.rs b/pumpkin-data/build/recipes.rs index bbefc6a48..5245f1fb1 100644 --- a/pumpkin-data/build/recipes.rs +++ b/pumpkin-data/build/recipes.rs @@ -50,9 +50,10 @@ impl ToTokens for CookingRecipeStruct { Some(category) => category.to_token_stream(), None => RecipeCategoryTypes::Misc.to_token_stream(), }; - let group = match &self.group { - Some(group) => quote! { Some(#group) }, - None => quote! { None }, + let group = if let Some(group) = &self.group { + quote! { Some(#group) } + } else { + quote! { None } }; let ingredient = self.ingredient.to_token_stream(); let cookingtime = self.cookingtime.to_token_stream(); @@ -88,9 +89,10 @@ impl ToTokens for CraftingShapedRecipeStruct { Some(category) => category.to_token_stream(), None => RecipeCategoryTypes::Misc.to_token_stream(), }; - let group = match &self.group { - Some(group) => quote! { Some(#group) }, - None => quote! { None }, + let group = if let Some(group) = &self.group { + quote! { Some(#group) } + } else { + quote! { None } }; let show_notification = self.show_notification.unwrap_or(true); let key = self @@ -104,7 +106,7 @@ impl ToTokens for CraftingShapedRecipeStruct { let pattern = self .pattern .iter() - .map(|c| c.to_token_stream()) + .map(quote::ToTokens::to_token_stream) .collect::>(); let result = self.result.to_token_stream(); @@ -135,14 +137,15 @@ impl ToTokens for CraftingShapelessRecipeStruct { Some(category) => category.to_token_stream(), None => RecipeCategoryTypes::Misc.to_token_stream(), }; - let group = match &self.group { - Some(group) => quote! { Some(#group) }, - None => quote! { None }, + let group = if let Some(group) = &self.group { + quote! { Some(#group) } + } else { + quote! { None } }; let ingredients = self .ingredients .iter() - .map(|c| c.to_token_stream()) + .map(quote::ToTokens::to_token_stream) .collect::>(); let result = self.result.to_token_stream(); @@ -172,9 +175,10 @@ impl ToTokens for CraftingTransmuteRecipeStruct { Some(category) => category.to_token_stream(), None => RecipeCategoryTypes::Misc.to_token_stream(), }; - let group = match &self.group { - Some(group) => quote! { Some(#group) }, - None => quote! { None }, + let group = if let Some(group) = &self.group { + quote! { Some(#group) } + } else { + quote! { None } }; let input = self.input.to_token_stream(); let material = self.material.to_token_stream(); @@ -243,17 +247,17 @@ pub enum RecipeIngredientTypes { impl ToTokens for RecipeIngredientTypes { fn to_tokens(&self, tokens: &mut TokenStream) { let name = match self { - RecipeIngredientTypes::Simple(ingredient) => { - if ingredient.starts_with("#") { + Self::Simple(ingredient) => { + if ingredient.starts_with('#') { quote! { RecipeIngredientTypes::Tagged(#ingredient) } } else { quote! { RecipeIngredientTypes::Simple(#ingredient) } } } - RecipeIngredientTypes::OneOf(ingredients) => { + Self::OneOf(ingredients) => { let ingredients = ingredients .iter() - .map(|c| c.to_token_stream()) + .map(quote::ToTokens::to_token_stream) .collect::>(); quote! { RecipeIngredientTypes::OneOf(&[#(#ingredients),*]) } } @@ -282,22 +286,22 @@ pub enum RecipeCategoryTypes { impl ToTokens for RecipeCategoryTypes { fn to_tokens(&self, tokens: &mut TokenStream) { let name = match self { - RecipeCategoryTypes::Equipment => { + Self::Equipment => { quote! { RecipeCategoryTypes::Equipment } } - RecipeCategoryTypes::Building => { + Self::Building => { quote! { RecipeCategoryTypes::Building } } - RecipeCategoryTypes::Restone => { + Self::Restone => { quote! { RecipeCategoryTypes::Restone } } - RecipeCategoryTypes::Misc => { + Self::Misc => { quote! { RecipeCategoryTypes::Misc } } - RecipeCategoryTypes::Food => { + Self::Food => { quote! { RecipeCategoryTypes::Food } } - RecipeCategoryTypes::Blocks => { + Self::Blocks => { quote! { RecipeCategoryTypes::Blocks } } }; diff --git a/pumpkin-data/build/registry.rs b/pumpkin-data/build/registry.rs index 78040ac7c..f2ec6cb59 100644 --- a/pumpkin-data/build/registry.rs +++ b/pumpkin-data/build/registry.rs @@ -9,8 +9,7 @@ pub(crate) fn build() -> TokenStream { println!("cargo:rerun-if-changed=../assets/registry/1_21_11_synced_registries.json"); let process_version = |path: &str| -> TokenStream { - let json_str = - fs::read_to_string(path).unwrap_or_else(|_| panic!("Failed to read {}", path)); + let json_str = fs::read_to_string(path).unwrap_or_else(|_| panic!("Failed to read {path}")); let mut data: IndexMap> = serde_json::from_str(&json_str).expect("Failed to parse JSON"); diff --git a/pumpkin-data/build/tag.rs b/pumpkin-data/build/tag.rs index 6bf606d48..0ecfbd717 100644 --- a/pumpkin-data/build/tag.rs +++ b/pumpkin-data/build/tag.rs @@ -115,7 +115,7 @@ pub(crate) fn build() -> TokenStream { let versions = vec![latest_version_key, legacy_version_key]; for version in versions { - let file_path = format!("../assets/tags/{}_tags.json", version); + let file_path = format!("../assets/tags/{version}_tags.json"); if !Path::new(&file_path).exists() { continue; } @@ -144,13 +144,13 @@ pub(crate) fn build() -> TokenStream { let ids: Vec = values .iter() .filter_map(|v| match key.as_str() { - "worldgen/biome" => biomes.get(v).map(|b| b.id as u16), + "worldgen/biome" => biomes.get(v).map(|b| u16::from(b.id)), "fluid" => fluid_id_map.get(v).copied(), "item" => items.get(v).map(|i| i.id), "block" => block_id_map.get(v).copied(), "enchantment" => enchantments - .get(&format!("minecraft:{}", v)) - .map(|e| e.id as u16), + .get(&format!("minecraft:{v}")) + .map(|e| u16::from(e.id)), "entity_type" => entities.get(v).map(|e| e.id), _ => None, }) diff --git a/pumpkin-data/build/tracked_data.rs b/pumpkin-data/build/tracked_data.rs index 7a2ee9022..058e16d9a 100644 --- a/pumpkin-data/build/tracked_data.rs +++ b/pumpkin-data/build/tracked_data.rs @@ -24,7 +24,7 @@ pub(crate) fn build() -> TokenStream { for (name, id_11) in &data_11 { let ident = format_ident!("DATA_{}", name.to_uppercase()); - let id_7 = data_7.get(name).cloned().unwrap_or(255); // 255 as an 'Invalid' marker + let id_7 = data_7.get(name).copied().unwrap_or(255); // 255 as an 'Invalid' marker constants.extend(quote! { pub const #ident: TrackedId = TrackedId { diff --git a/pumpkin-data/src/block_direction.rs b/pumpkin-data/src/block_direction.rs index 0b70dc386..995cde1f5 100644 --- a/pumpkin-data/src/block_direction.rs +++ b/pumpkin-data/src/block_direction.rs @@ -27,7 +27,7 @@ impl From for Axis { } } impl From for MathAxis { - fn from(a: Axis) -> MathAxis { + fn from(a: Axis) -> Self { match a { Axis::X => Self::X, Axis::Y => Self::Y, @@ -55,17 +55,19 @@ impl TryFrom for BlockDirection { } impl BlockDirection { + #[must_use] pub fn to_index(&self) -> u8 { match self { - BlockDirection::Down => 0, - BlockDirection::Up => 1, - BlockDirection::North => 2, - BlockDirection::South => 3, - BlockDirection::West => 4, - BlockDirection::East => 5, + Self::Down => 0, + Self::Up => 1, + Self::North => 2, + Self::South => 3, + Self::West => 4, + Self::East => 5, } } + #[must_use] pub fn from_index(index: u8) -> Option { match index { 0 => Some(Self::Down), @@ -86,176 +88,173 @@ impl BlockDirection { Self::horizontal()[random.next_bounded_i32(Self::horizontal().len() as i32 - 1) as usize] } + #[must_use] pub fn by_index(index: usize) -> Option { - Self::all().get(index % Self::all().len()).cloned() + Self::all().get(index % Self::all().len()).copied() } + #[must_use] pub fn to_offset(&self) -> Vector3 { match self { - BlockDirection::Down => (0, -1, 0), - BlockDirection::Up => (0, 1, 0), - BlockDirection::North => (0, 0, -1), - BlockDirection::South => (0, 0, 1), - BlockDirection::West => (-1, 0, 0), - BlockDirection::East => (1, 0, 0), + Self::Down => (0, -1, 0), + Self::Up => (0, 1, 0), + Self::North => (0, 0, -1), + Self::South => (0, 0, 1), + Self::West => (-1, 0, 0), + Self::East => (1, 0, 0), } .into() } - pub fn opposite(&self) -> BlockDirection { + #[must_use] + pub fn opposite(&self) -> Self { match self { - BlockDirection::Down => BlockDirection::Up, - BlockDirection::Up => BlockDirection::Down, - BlockDirection::North => BlockDirection::South, - BlockDirection::South => BlockDirection::North, - BlockDirection::West => BlockDirection::East, - BlockDirection::East => BlockDirection::West, + Self::Down => Self::Up, + Self::Up => Self::Down, + Self::North => Self::South, + Self::South => Self::North, + Self::West => Self::East, + Self::East => Self::West, } } + #[must_use] pub fn positive(&self) -> bool { matches!(self, Self::South | Self::East | Self::Up) } - pub fn all() -> [BlockDirection; 6] { + #[must_use] + pub fn all() -> [Self; 6] { [ - BlockDirection::Down, - BlockDirection::Up, - BlockDirection::North, - BlockDirection::South, - BlockDirection::West, - BlockDirection::East, + Self::Down, + Self::Up, + Self::North, + Self::South, + Self::West, + Self::East, ] } - pub fn update_order() -> [BlockDirection; 6] { + #[must_use] + pub fn update_order() -> [Self; 6] { [ - BlockDirection::West, - BlockDirection::East, - BlockDirection::Down, - BlockDirection::Up, - BlockDirection::North, - BlockDirection::South, + Self::West, + Self::East, + Self::Down, + Self::Up, + Self::North, + Self::South, ] } - pub fn abstract_block_update_order() -> [BlockDirection; 6] { + #[must_use] + pub fn abstract_block_update_order() -> [Self; 6] { [ - BlockDirection::West, - BlockDirection::East, - BlockDirection::North, - BlockDirection::South, - BlockDirection::Down, - BlockDirection::Up, + Self::West, + Self::East, + Self::North, + Self::South, + Self::Down, + Self::Up, ] } - pub fn horizontal() -> [BlockDirection; 4] { - [ - BlockDirection::North, - BlockDirection::South, - BlockDirection::West, - BlockDirection::East, - ] + #[must_use] + pub fn horizontal() -> [Self; 4] { + [Self::North, Self::South, Self::West, Self::East] } - pub fn flow_directions() -> [BlockDirection; 5] { - [ - BlockDirection::Down, - BlockDirection::North, - BlockDirection::South, - BlockDirection::West, - BlockDirection::East, - ] + #[must_use] + pub fn flow_directions() -> [Self; 5] { + [Self::Down, Self::North, Self::South, Self::West, Self::East] } + #[must_use] pub fn is_horizontal(&self) -> bool { - matches!( - self, - BlockDirection::North - | BlockDirection::South - | BlockDirection::West - | BlockDirection::East - ) + matches!(self, Self::North | Self::South | Self::West | Self::East) } - pub fn vertical() -> [BlockDirection; 2] { - [BlockDirection::Down, BlockDirection::Up] + #[must_use] + pub fn vertical() -> [Self; 2] { + [Self::Down, Self::Up] } + #[must_use] pub fn to_horizontal_facing(&self) -> Option { match self { - BlockDirection::North => Some(HorizontalFacing::North), - BlockDirection::South => Some(HorizontalFacing::South), - BlockDirection::West => Some(HorizontalFacing::West), - BlockDirection::East => Some(HorizontalFacing::East), + Self::North => Some(HorizontalFacing::North), + Self::South => Some(HorizontalFacing::South), + Self::West => Some(HorizontalFacing::West), + Self::East => Some(HorizontalFacing::East), _ => None, } } + #[must_use] pub fn to_horizontal_axis(&self) -> Option { match self { - BlockDirection::North | BlockDirection::South => Some(HorizontalAxis::Z), - BlockDirection::West | BlockDirection::East => Some(HorizontalAxis::X), + Self::North | Self::South => Some(HorizontalAxis::Z), + Self::West | Self::East => Some(HorizontalAxis::X), _ => None, } } + #[must_use] pub fn to_cardinal_direction(&self) -> HorizontalFacing { match self { - BlockDirection::North => HorizontalFacing::North, - BlockDirection::South => HorizontalFacing::South, - BlockDirection::West => HorizontalFacing::West, - BlockDirection::East => HorizontalFacing::East, + Self::South => HorizontalFacing::South, + Self::West => HorizontalFacing::West, + Self::East => HorizontalFacing::East, _ => HorizontalFacing::North, } } - pub fn from_cardinal_direction(direction: HorizontalFacing) -> BlockDirection { + #[must_use] + pub fn from_cardinal_direction(direction: HorizontalFacing) -> Self { match direction { - HorizontalFacing::North => BlockDirection::North, - HorizontalFacing::South => BlockDirection::South, - HorizontalFacing::West => BlockDirection::West, - HorizontalFacing::East => BlockDirection::East, + HorizontalFacing::North => Self::North, + HorizontalFacing::South => Self::South, + HorizontalFacing::West => Self::West, + HorizontalFacing::East => Self::East, } } + #[must_use] pub fn to_axis(&self) -> Axis { match self { - BlockDirection::North | BlockDirection::South => Axis::Z, - BlockDirection::West | BlockDirection::East => Axis::X, - BlockDirection::Up | BlockDirection::Down => Axis::Y, + Self::North | Self::South => Axis::Z, + Self::West | Self::East => Axis::X, + Self::Up | Self::Down => Axis::Y, } } + #[must_use] pub fn to_facing(&self) -> Facing { match self { - BlockDirection::North => Facing::North, - BlockDirection::South => Facing::South, - BlockDirection::West => Facing::West, - BlockDirection::East => Facing::East, - BlockDirection::Up => Facing::Up, - BlockDirection::Down => Facing::Down, + Self::North => Facing::North, + Self::South => Facing::South, + Self::West => Facing::West, + Self::East => Facing::East, + Self::Up => Facing::Up, + Self::Down => Facing::Down, } } - pub fn rotate_clockwise(&self) -> BlockDirection { + #[must_use] + pub fn rotate_clockwise(&self) -> Self { match self { - BlockDirection::North => BlockDirection::East, - BlockDirection::East => BlockDirection::South, - BlockDirection::South => BlockDirection::West, - BlockDirection::West => BlockDirection::North, - BlockDirection::Up => BlockDirection::East, - BlockDirection::Down => BlockDirection::West, + Self::East => Self::South, + Self::West => Self::North, + Self::Up | Self::North => Self::East, + Self::Down | Self::South => Self::West, } } - pub fn rotate_counter_clockwise(&self) -> BlockDirection { + #[must_use] + pub fn rotate_counter_clockwise(&self) -> Self { match self { - BlockDirection::North => BlockDirection::West, - BlockDirection::West => BlockDirection::South, - BlockDirection::South => BlockDirection::East, - BlockDirection::East => BlockDirection::North, - BlockDirection::Up => BlockDirection::West, - BlockDirection::Down => BlockDirection::East, + Self::West => Self::South, + Self::East => Self::North, + Self::Up | Self::North => Self::West, + Self::Down | Self::South => Self::East, } } } diff --git a/pumpkin-data/src/block_state.rs b/pumpkin-data/src/block_state.rs index 0b39e6012..7f87d84fa 100644 --- a/pumpkin-data/src/block_state.rs +++ b/pumpkin-data/src/block_state.rs @@ -52,35 +52,43 @@ pub enum PistonBehavior { } impl BlockState { + #[must_use] pub const fn is_air(&self) -> bool { self.state_flags & IS_AIR != 0 } + #[must_use] pub const fn burnable(&self) -> bool { self.state_flags & BURNABLE != 0 } + #[must_use] pub const fn tool_required(&self) -> bool { self.state_flags & TOOL_REQUIRED != 0 } + #[must_use] pub const fn sided_transparency(&self) -> bool { self.state_flags & SIDED_TRANSPARENCY != 0 } + #[must_use] pub const fn replaceable(&self) -> bool { self.state_flags & REPLACEABLE != 0 } + #[must_use] pub const fn is_liquid(&self) -> bool { self.state_flags & IS_LIQUID != 0 } /// Returns the legacy value for whether a block is solid. + #[must_use] pub const fn is_solid(&self) -> bool { self.state_flags & IS_SOLID != 0 } + #[must_use] pub const fn is_full_cube(&self) -> bool { self.state_flags & IS_FULL_CUBE != 0 } @@ -88,15 +96,18 @@ impl BlockState { /// Returns whether the block is solid. /// Solid blocks conduct redstone and block redstone wire. /// Non-solid blocks don't allow redstone wire on top to propagate their signal downwards in java. + #[must_use] pub const fn is_solid_block(&self) -> bool { self.state_flags & IS_SOLID_BLOCK != 0 } + #[must_use] pub const fn has_random_ticks(&self) -> bool { self.state_flags & HAS_RANDOM_TICKS != 0 } - ///isSideSolidFullSquare() in Java! + ///`isSideSolidFullSquare()` in Java! + #[must_use] pub const fn is_side_solid(&self, side: BlockDirection) -> bool { match side { BlockDirection::Down => self.side_flags & DOWN_SIDE_SOLID != 0, @@ -110,6 +121,7 @@ impl BlockState { ///isSideSolid(..., Direction.UP, SideShapeType.CENTER) in Java! ///Only valid for UP and DOWN sides + #[must_use] pub const fn is_center_solid(&self, side: BlockDirection) -> bool { match side { BlockDirection::Down => self.side_flags & DOWN_CENTER_SOLID != 0, @@ -118,17 +130,16 @@ impl BlockState { } } + #[must_use] pub fn is_waterlogged(&self) -> bool { let block = Block::from_state_id(self.id); - if let Some(props) = block.properties(self.id) { + block.properties(self.id).is_some_and(|props| { props .to_props() .iter() .any(|(k, v)| k == &"waterlogged" && v == &"true") - } else { - false - } + }) } pub fn get_block_collision_shapes(&self) -> impl Iterator + '_ { @@ -143,14 +154,9 @@ impl BlockState { .iter() .map(|&id| COLLISION_SHAPES[id as usize]); - let water_shape = if self.is_waterlogged() { - Some(CollisionShape::new( - Vector3::new(0.0, 0.0, 0.0), - Vector3::new(1.0, 0.875, 1.0), - )) - } else { - None - }; + let water_shape = self.is_waterlogged().then(|| { + CollisionShape::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(1.0, 0.875, 1.0)) + }); base_shapes.chain(water_shape) } diff --git a/pumpkin-data/src/blocks.rs b/pumpkin-data/src/blocks.rs index bbeb3a515..94dfcb642 100644 --- a/pumpkin-data/src/blocks.rs +++ b/pumpkin-data/src/blocks.rs @@ -18,9 +18,9 @@ use std::hash::{Hash, Hasher}; pub struct Block { /// The numeric ID used for internal registry mapping. pub id: u16, - /// The unique namespaced ID (e.g., "diamond_ore"). + /// The unique namespaced ID (e.g., "`diamond_ore`"). pub name: &'static str, - /// The key used for client-side localization (e.g., "block.minecraft.diamond_ore"). + /// The key used for client-side localization (e.g., "`block.minecraft.diamond_ore`"). pub translation_key: &'static str, /// How hard the block is to break. A value of -1.0 indicates an unbreakable block (e.g., Bedrock). pub hardness: f32, @@ -102,6 +102,7 @@ impl FromResourceLocation for &'static Block { } impl Block { + #[must_use] pub fn is_waterlogged(&self, state_id: u16) -> bool { self.properties(state_id).is_some_and(|properties| { properties diff --git a/pumpkin-data/src/collision_shape.rs b/pumpkin-data/src/collision_shape.rs index 2421283a4..8a7f0c040 100644 --- a/pumpkin-data/src/collision_shape.rs +++ b/pumpkin-data/src/collision_shape.rs @@ -7,6 +7,7 @@ pub struct CollisionShape { } impl CollisionShape { + #[must_use] pub fn to_bounding_box(&self) -> BoundingBox { BoundingBox { min: self.min, @@ -14,10 +15,12 @@ impl CollisionShape { } } + #[must_use] pub fn new(min: Vector3, max: Vector3) -> Self { Self { min, max } } + #[must_use] pub fn intersects(&self, other: &BoundingBox) -> bool { self.min.x < other.max.x && self.max.x > other.min.x @@ -27,11 +30,12 @@ impl CollisionShape { && self.max.z > other.min.z } + #[must_use] pub fn at_pos(&self, pos: BlockPos) -> Self { let vec3 = Vector3 { - x: pos.0.x as f64, - y: pos.0.y as f64, - z: pos.0.z as f64, + x: f64::from(pos.0.x), + y: f64::from(pos.0.y), + z: f64::from(pos.0.z), }; Self { min: self.min + vec3, diff --git a/pumpkin-data/src/data_component_impl.rs b/pumpkin-data/src/data_component_impl.rs index a8d3541d8..289879ae6 100644 --- a/pumpkin-data/src/data_component_impl.rs +++ b/pumpkin-data/src/data_component_impl.rs @@ -2,7 +2,11 @@ use crate::attributes::Attributes; use crate::data_component::DataComponent; -use crate::data_component::DataComponent::*; +use crate::data_component::DataComponent::{ + AttributeModifiers, BlocksAttacks, Consumable, CustomData, CustomName, Damage, DeathProtection, + Enchantments, Equippable, Food, ItemName, JukeboxPlayable, MaxDamage, MaxStackSize, Tool, + Unbreakable, +}; use crate::entity_type::EntityType; use crate::tag::{Tag, Taggable}; use crate::{AttributeModifierSlot, Block, Enchantment}; @@ -38,6 +42,7 @@ pub trait DataComponentImpl: Send + Sync { fn as_any(&self) -> &dyn Any; fn as_mut_any(&mut self) -> &mut dyn Any; } +#[must_use] pub fn read_data(id: DataComponent, data: &NbtTag) -> Option> { match id { MaxStackSize => Some(MaxStackSizeImpl::read_data(data)?.to_dyn()), @@ -116,10 +121,10 @@ impl MaxStackSizeImpl { } impl DataComponentImpl for MaxStackSizeImpl { fn write_data(&self) -> NbtTag { - NbtTag::Int(self.size as i32) + NbtTag::Int(i32::from(self.size)) } fn get_hash(&self) -> i32 { - get_i32_hash(self.size as i32) as i32 + get_i32_hash(i32::from(self.size)) as i32 } default_impl!(MaxStackSize); @@ -196,7 +201,7 @@ impl EnchantmentsImpl { let data = &data.extract_compound()?.child_tags; let mut enc = Vec::with_capacity(data.len()); for (name, level) in data { - enc.push((Enchantment::from_name(name.as_str())?, level.extract_int()?)) + enc.push((Enchantment::from_name(name.as_str())?, level.extract_int()?)); } Some(Self { enchantment: Cow::from(enc), @@ -279,7 +284,7 @@ impl Hash for Modifier { fn hash(&self, state: &mut H) { self.r#type.hash(state); self.id.hash(state); - unsafe { (*(&self.amount as *const f64 as *const u64)).hash(state) }; + unsafe { (*(&raw const self.amount).cast::()).hash(state) }; self.operation.hash(state); self.slot.hash(state); } @@ -315,7 +320,7 @@ impl DataComponentImpl for FoodImpl { impl Hash for FoodImpl { fn hash(&self, state: &mut H) { self.nutrition.hash(state); - unsafe { (*(&self.saturation as *const f32 as *const u32)).hash(state) }; + unsafe { (*(&raw const self.saturation).cast::()).hash(state) }; self.can_always_eat.hash(state); } } @@ -326,6 +331,7 @@ pub struct ConsumableImpl { } impl ConsumableImpl { + #[must_use] pub fn consume_ticks(&self) -> i32 { (self.consume_seconds * 20.0) as i32 } @@ -336,7 +342,7 @@ impl DataComponentImpl for ConsumableImpl { } impl Hash for ConsumableImpl { fn hash(&self, state: &mut H) { - unsafe { (*(&self.consume_seconds as *const f32 as *const u32)).hash(state) }; + unsafe { (*(&raw const self.consume_seconds).cast::()).hash(state) }; } } #[derive(Clone, Debug, Hash, PartialEq)] @@ -363,7 +369,7 @@ impl Hash for ToolRule { self.blocks.hash(state); if let Some(val) = self.speed { true.hash(state); - unsafe { (*(&val as *const f32 as *const u32)).hash(state) }; + unsafe { (*(&raw const val).cast::()).hash(state) }; } else { false.hash(state); } @@ -383,7 +389,7 @@ impl DataComponentImpl for ToolImpl { impl Hash for ToolImpl { fn hash(&self, state: &mut H) { self.rules.hash(state); - unsafe { (*(&self.default_mining_speed as *const f32 as *const u32)).hash(state) }; + unsafe { (*(&raw const self.default_mining_speed).cast::()).hash(state) }; self.damage_per_block.hash(state); self.can_destroy_blocks_in_creative.hash(state); } @@ -479,6 +485,7 @@ impl EquipmentSlot { name: Cow::Borrowed("saddle"), }); + #[must_use] pub fn get_entity_slot_id(&self) -> i32 { match self { Self::MainHand(data) => data.entity_id, @@ -492,6 +499,7 @@ impl EquipmentSlot { } } + #[must_use] pub fn get_from_name(name: &str) -> Option { match name { "mainhand" => Some(Self::MAIN_HAND), @@ -506,10 +514,12 @@ impl EquipmentSlot { } } + #[must_use] pub fn get_offset_entity_slot_id(&self, offset: i32) -> i32 { self.get_entity_slot_id() + offset } + #[must_use] pub fn slot_type(&self) -> EquipmentType { match self { Self::MainHand(data) => data.slot_type, @@ -523,6 +533,7 @@ impl EquipmentSlot { } } + #[must_use] pub fn is_armor_slot(&self) -> bool { matches!( self.slot_type(), @@ -530,6 +541,7 @@ impl EquipmentSlot { ) } + #[must_use] pub const fn discriminant(&self) -> i8 { match self { Self::MainHand(_) => 0, @@ -553,12 +565,12 @@ pub enum EntityTypeOrTag { impl Hash for EntityTypeOrTag { fn hash(&self, state: &mut H) { match self { - EntityTypeOrTag::Tag(tag) => { + Self::Tag(tag) => { for x in tag.0 { x.hash(state); } } - EntityTypeOrTag::Single(entity_type) => { + Self::Single(entity_type) => { entity_type.id.hash(state); } } diff --git a/pumpkin-inventory/Cargo.toml b/pumpkin-inventory/Cargo.toml index 818ed1ba1..3b432cff1 100644 --- a/pumpkin-inventory/Cargo.toml +++ b/pumpkin-inventory/Cargo.toml @@ -15,3 +15,6 @@ log.workspace = true tokio.workspace = true thiserror.workspace = true crossbeam-utils.workspace = true + +[lints] +workspace = true diff --git a/pumpkin-inventory/src/container_click.rs b/pumpkin-inventory/src/container_click.rs index e9497b61a..6730c1b31 100644 --- a/pumpkin-inventory/src/container_click.rs +++ b/pumpkin-inventory/src/container_click.rs @@ -17,7 +17,7 @@ const KEY_CLICK_HOTBAR_END: i8 = 9; const SLOT_INDEX_OUTSIDE: i16 = -999; impl Click { - pub fn new(mode: SlotActionType, button: i8, slot: i16) -> Result { + pub fn new(mode: &SlotActionType, button: i8, slot: i16) -> Result { match mode { SlotActionType::Pickup => Self::new_normal_click(button, slot), // Both buttons do the same here, so we omit it @@ -37,12 +37,11 @@ impl Click { } fn new_normal_click(button: i8, slot: i16) -> Result { - let slot = match slot { - SLOT_INDEX_OUTSIDE => Slot::OutsideInventory, - _ => { - let slot = slot.try_into().unwrap_or(0); - Slot::Normal(slot) - } + let slot = if slot == SLOT_INDEX_OUTSIDE { + Slot::OutsideInventory + } else { + let slot = slot.try_into().unwrap_or(0); + Slot::Normal(slot) }; let button = match button { BUTTON_CLICK_LEFT => MouseClick::Left, @@ -79,12 +78,11 @@ impl Click { fn new_drop_item(button: i8, slot: i16) -> Result { let drop_type = DropType::from_i8(button)?; - let slot = match slot { - SLOT_INDEX_OUTSIDE => Slot::OutsideInventory, - _ => { - let slot = slot.try_into().unwrap_or(0); - Slot::Normal(slot) - } + let slot = if slot == SLOT_INDEX_OUTSIDE { + Slot::OutsideInventory + } else { + let slot = slot.try_into().unwrap_or(0); + Slot::Normal(slot) }; Ok(Self { click_type: ClickType::DropType(drop_type), diff --git a/pumpkin-inventory/src/crafting/crafting_inventory.rs b/pumpkin-inventory/src/crafting/crafting_inventory.rs index a2964dc28..9fb4d1b75 100644 --- a/pumpkin-inventory/src/crafting/crafting_inventory.rs +++ b/pumpkin-inventory/src/crafting/crafting_inventory.rs @@ -16,6 +16,7 @@ pub struct CraftingInventory { } impl CraftingInventory { + #[must_use] pub fn new(width: u8, height: u8) -> Self { Self { width, @@ -38,7 +39,7 @@ impl Inventory for CraftingInventory { fn is_empty(&self) -> InventoryFuture<'_, bool> { Box::pin(async move { - for slot in self.items.iter() { + for slot in &self.items { if !slot.lock().await.is_empty() { return false; } @@ -89,7 +90,7 @@ impl RecipeInputInventory for CraftingInventory { impl Clearable for CraftingInventory { fn clear(&self) -> Pin + Send + '_>> { Box::pin(async move { - for item in self.items.iter() { + for item in &self.items { *item.lock().await = ItemStack::EMPTY.clone(); } }) diff --git a/pumpkin-inventory/src/crafting/crafting_screen_handler.rs b/pumpkin-inventory/src/crafting/crafting_screen_handler.rs index 813747285..aa1046775 100644 --- a/pumpkin-inventory/src/crafting/crafting_screen_handler.rs +++ b/pumpkin-inventory/src/crafting/crafting_screen_handler.rs @@ -48,6 +48,7 @@ fn is_symmetrical_horizontally(pattern: &'static [&'static str]) -> bool { true } +#[expect(clippy::too_many_lines)] async fn recipe_matches<'a>( recipe: &'static CraftingRecipeTypes, input_height: usize, @@ -146,7 +147,7 @@ async fn recipe_matches<'a>( } // TODO: Apply components - if matched { Some(result) } else { None } + matched.then_some(result) } CraftingRecipeTypes::CraftingShapeless { ingredients, @@ -234,7 +235,7 @@ async fn recipe_matches<'a>( } impl ResultSlot { - fn stat_crafted(&self, _crafted_amount: u8, _player: &dyn InventoryPlayer) {} + //fn stat_crafted(&self, _crafted_amount: u8, _player: &dyn InventoryPlayer) {} pub fn new(inventory: Arc) -> Self { Self { @@ -315,8 +316,7 @@ impl ResultSlot { let result = self .match_recipe() .await - .map(|x| ItemStack::from(x.0)) - .unwrap_or(ItemStack::EMPTY.clone()); + .map_or(ItemStack::EMPTY.clone(), |x| ItemStack::from(x.0)); *self.result.lock().await = result.clone(); result } @@ -348,8 +348,8 @@ impl Slot for ResultSlot { fn on_take_item<'a>( &'a self, - player: &'a dyn InventoryPlayer, - stack: &'a ItemStack, + _player: &'a dyn InventoryPlayer, + _stack: &'a ItemStack, ) -> BoxFuture<'a, ()> { Box::pin(async move { for i in 0..self.inventory.size() { @@ -360,7 +360,8 @@ impl Slot for ResultSlot { stack.item_count -= 1; } } - self.stat_crafted(stack.item_count, player); + // TODO + //self.stat_crafted(stack.item_count, player); self.mark_dirty().await; }) } @@ -489,7 +490,7 @@ impl CraftingTableScreenHandler { let crafting_inventory: Arc = Arc::new(CraftingInventory::new(3, 3)); - let mut crafting_table_handler = CraftingTableScreenHandler { + let mut crafting_table_handler = Self { behaviour: ScreenHandlerBehaviour::new(sync_id, Some(WindowType::Crafting)), crafting_inventory: crafting_inventory.clone(), }; diff --git a/pumpkin-inventory/src/crafting/recipes.rs b/pumpkin-inventory/src/crafting/recipes.rs index 218863eb5..b2b2e7e31 100644 --- a/pumpkin-inventory/src/crafting/recipes.rs +++ b/pumpkin-inventory/src/crafting/recipes.rs @@ -1,10 +1,10 @@ use pumpkin_world::inventory::Inventory; // RecipeMatcher.java -pub struct RecipeMatcher {} +pub struct RecipeMatcher; // RecipeFinder.java -pub struct RecipeFinder {} +pub struct RecipeFinder; // AbstractRecipeScreenHandle.java pub trait RecipeFinderScreenHandler {} diff --git a/pumpkin-inventory/src/double.rs b/pumpkin-inventory/src/double.rs index 12dbe175b..88933a749 100644 --- a/pumpkin-inventory/src/double.rs +++ b/pumpkin-inventory/src/double.rs @@ -65,9 +65,9 @@ impl Inventory for DoubleInventory { fn set_stack(&self, slot: usize, stack: ItemStack) -> InventoryFuture<'_, ()> { Box::pin(async move { if slot >= self.first.size() { - self.second.set_stack(slot - self.first.size(), stack).await + self.second.set_stack(slot - self.first.size(), stack).await; } else { - self.first.set_stack(slot, stack).await + self.first.set_stack(slot, stack).await; } }) } diff --git a/pumpkin-inventory/src/entity_equipment.rs b/pumpkin-inventory/src/entity_equipment.rs index 98f7ce4cf..f8df375d9 100644 --- a/pumpkin-inventory/src/entity_equipment.rs +++ b/pumpkin-inventory/src/entity_equipment.rs @@ -17,6 +17,7 @@ impl Default for EntityEquipment { } impl EntityEquipment { + #[must_use] pub fn new() -> Self { Self { equipment: HashMap::new(), @@ -32,6 +33,7 @@ impl EntityEquipment { .clone() } + #[must_use] pub fn get(&self, slot: &EquipmentSlot) -> Arc> { self.equipment .get(slot) diff --git a/pumpkin-inventory/src/furnace_like/furnace_like_screen_handler.rs b/pumpkin-inventory/src/furnace_like/furnace_like_screen_handler.rs index 347b63ca4..c70a4cee1 100644 --- a/pumpkin-inventory/src/furnace_like/furnace_like_screen_handler.rs +++ b/pumpkin-inventory/src/furnace_like/furnace_like_screen_handler.rs @@ -26,12 +26,6 @@ impl FurnaceLikeScreenHandler { furnace_block_entity: Arc, window_type: WindowType, ) -> Self { - let furnace_like_property_delegate = furnace_block_entity.to_property_delegate().unwrap(); - let mut handler = Self { - inventory, - behaviour: ScreenHandlerBehaviour::new(sync_id, Some(window_type)), - }; - struct FurnaceLikeScreenListener; impl ScreenHandlerListener for FurnaceLikeScreenListener { fn on_property_update<'a>( @@ -43,12 +37,17 @@ impl FurnaceLikeScreenHandler { Box::pin(async move { if let Some(sync_handler) = screen_handler.sync_handler.as_ref() { sync_handler - .update_property(screen_handler, property as i32, value) + .update_property(screen_handler, i32::from(property), value) .await; } }) } } + let furnace_like_property_delegate = furnace_block_entity.to_property_delegate().unwrap(); + let mut handler = Self { + inventory, + behaviour: ScreenHandlerBehaviour::new(sync_id, Some(window_type)), + }; // 0: Fire icon (fuel left) counting from fuel burn time down to 0 (in-game ticks) // 1: Maximum fuel burn time fuel burn time or 0 (in-game ticks) diff --git a/pumpkin-inventory/src/generic_container_screen_handler.rs b/pumpkin-inventory/src/generic_container_screen_handler.rs index 30f6e7543..e4d6c9ba8 100644 --- a/pumpkin-inventory/src/generic_container_screen_handler.rs +++ b/pumpkin-inventory/src/generic_container_screen_handler.rs @@ -161,7 +161,7 @@ impl ScreenHandler for GenericContainerScreenHandler { // Re-acquire lock for insert_item (which expects &mut ItemStack) let mut slot_stack_mut = slot_stack_lock.lock().await; - if slot_index < (self.rows * 9) as i32 { + if slot_index < i32::from(self.rows * 9) { // Move from inventory to player area (end) if !self .insert_item( diff --git a/pumpkin-inventory/src/lib.rs b/pumpkin-inventory/src/lib.rs index 874ae279e..cfa744ef7 100644 --- a/pumpkin-inventory/src/lib.rs +++ b/pumpkin-inventory/src/lib.rs @@ -19,6 +19,7 @@ use pumpkin_data::data_component_impl::EquipmentSlot; use crate::player::player_inventory::PlayerInventory; +#[must_use] pub fn build_equipment_slots() -> HashMap { let mut equipment_slots = HashMap::new(); equipment_slots.insert( diff --git a/pumpkin-inventory/src/player/ender_chest_inventory.rs b/pumpkin-inventory/src/player/ender_chest_inventory.rs index 34645693b..2a110e6a7 100644 --- a/pumpkin-inventory/src/player/ender_chest_inventory.rs +++ b/pumpkin-inventory/src/player/ender_chest_inventory.rs @@ -21,6 +21,7 @@ impl Default for EnderChestInventory { impl EnderChestInventory { pub const INVENTORY_SIZE: usize = 27; + #[must_use] pub fn new() -> Self { Self { items: from_fn(|_| Arc::new(Mutex::new(ItemStack::EMPTY.clone()))), @@ -51,7 +52,7 @@ impl Inventory for EnderChestInventory { fn is_empty(&self) -> InventoryFuture<'_, bool> { Box::pin(async move { - for slot in self.items.iter() { + for slot in &self.items { if !slot.lock().await.is_empty() { return false; } @@ -110,7 +111,7 @@ impl Inventory for EnderChestInventory { impl Clearable for EnderChestInventory { fn clear(&self) -> Pin + Send + '_>> { Box::pin(async move { - for item in self.items.iter() { + for item in &self.items { *item.lock().await = ItemStack::EMPTY.clone(); } }) diff --git a/pumpkin-inventory/src/player/player_inventory.rs b/pumpkin-inventory/src/player/player_inventory.rs index 0d4f2a10f..41804717b 100644 --- a/pumpkin-inventory/src/player/player_inventory.rs +++ b/pumpkin-inventory/src/player/player_inventory.rs @@ -58,18 +58,12 @@ impl PlayerInventory { /// getOffHandStack in source pub async fn off_hand_item(&self) -> Arc> { - let slot = self - .equipment_slots - .get(&PlayerInventory::OFF_HAND_SLOT) - .unwrap(); + let slot = self.equipment_slots.get(&Self::OFF_HAND_SLOT).unwrap(); self.entity_equipment.lock().await.get(slot) } pub async fn swap_item(&self) -> (ItemStack, ItemStack) { - let slot = self - .equipment_slots - .get(&PlayerInventory::OFF_HAND_SLOT) - .unwrap(); + let slot = self.equipment_slots.get(&Self::OFF_HAND_SLOT).unwrap(); let mut equipment = self.entity_equipment.lock().await; let binding = self.held_item(); let mut main_hand_item = binding.lock().await; @@ -78,6 +72,7 @@ impl PlayerInventory { (main_hand_item.clone(), off_hand_item) } + #[must_use] pub fn is_valid_hotbar_index(slot: usize) -> bool { slot < Self::HOTBAR_SIZE } @@ -109,13 +104,11 @@ impl PlayerInventory { let count_left = self_stack.get_max_stack_size() - self_stack.item_count; let count_min = stack_count.min(count_left); - if count_min == 0 { - stack_count as usize - } else { + if count_min != 0 { stack_count -= count_min; self_stack.increment(count_min); - stack_count as usize } + stack_count as usize } async fn get_empty_slot(&self) -> i16 { @@ -128,7 +121,7 @@ impl PlayerInventory { -1 } - fn can_stack_add_more(&self, existing_stack: &ItemStack, stack: &ItemStack) -> bool { + fn can_stack_add_more(existing_stack: &ItemStack, stack: &ItemStack) -> bool { !existing_stack.is_empty() && existing_stack.are_items_and_components_equal(stack) && existing_stack.is_stackable() @@ -136,7 +129,7 @@ impl PlayerInventory { } async fn get_occupied_slot_with_room_for_stack(&self, stack: &ItemStack) -> i16 { - if self.can_stack_add_more( + if Self::can_stack_add_more( &*self .get_stack(self.get_selected_slot() as usize) .await @@ -144,15 +137,15 @@ impl PlayerInventory { .await, stack, ) { - self.get_selected_slot() as i16 - } else if self.can_stack_add_more( + i16::from(self.get_selected_slot()) + } else if Self::can_stack_add_more( &*self.get_stack(Self::OFF_HAND_SLOT).await.lock().await, stack, ) { Self::OFF_HAND_SLOT as i16 } else { for i in 0..Self::MAIN_SIZE { - if self.can_stack_add_more(&*self.main_inventory[i].lock().await, stack) { + if Self::can_stack_add_more(&*self.main_inventory[i].lock().await, stack) { return i as i16; } } @@ -298,7 +291,7 @@ impl PlayerInventory { { player .enqueue_slot_set_packet(&CSetPlayerInventory::new( - (room_for_stack as i32).into(), + i32::from(room_for_stack).into(), &self .get_stack(room_for_stack as usize) .await @@ -316,7 +309,7 @@ impl PlayerInventory { impl Clearable for PlayerInventory { fn clear(&self) -> Pin + Send + '_>> { Box::pin(async move { - for item in self.main_inventory.iter() { + for item in &self.main_inventory { *item.lock().await = ItemStack::EMPTY.clone(); } @@ -332,7 +325,7 @@ impl Inventory for PlayerInventory { fn is_empty(&self) -> InventoryFuture<'_, bool> { Box::pin(async move { - for item in self.main_inventory.iter() { + for item in &self.main_inventory { if !item.lock().await.is_empty() { return false; } diff --git a/pumpkin-inventory/src/player/player_screen_handler.rs b/pumpkin-inventory/src/player/player_screen_handler.rs index 1e5b722fb..c0f5b3fbf 100644 --- a/pumpkin-inventory/src/player/player_screen_handler.rs +++ b/pumpkin-inventory/src/player/player_screen_handler.rs @@ -31,11 +31,12 @@ impl PlayerScreenHandler { EquipmentSlot::FEET, ]; + #[must_use] pub fn is_in_hotbar(slot: u8) -> bool { (36..=45).contains(&slot) } - pub async fn get_slot(&self, slot: usize) -> Arc { + pub fn get_slot(&self, slot: usize) -> Arc { self.behaviour.slots[slot].clone() } @@ -47,7 +48,7 @@ impl PlayerScreenHandler { let crafting_inventory: Arc = Arc::new(CraftingInventory::new(2, 2)); - let mut player_screen_handler = PlayerScreenHandler { + let mut player_screen_handler = Self { behaviour: ScreenHandlerBehaviour::new(sync_id, window_type), crafting_inventory: crafting_inventory.clone(), }; @@ -140,7 +141,6 @@ impl ScreenHandler for PlayerScreenHandler { } else if equipment_slot.slot_type() == EquipmentType::HumanoidArmor && self .get_slot((8 - equipment_slot.get_entity_slot_id()) as usize) - .await .get_cloned_stack() .await .is_empty() @@ -159,7 +159,7 @@ impl ScreenHandler for PlayerScreenHandler { result } else if matches!(equipment_slot, EquipmentSlot::OffHand(_)) && slot_index != 45 - && self.get_slot(45).await.get_cloned_stack().await.is_empty() + && self.get_slot(45).get_cloned_stack().await.is_empty() { // Into empty offhand slot (45) let index = 45; diff --git a/pumpkin-inventory/src/screen_handler.rs b/pumpkin-inventory/src/screen_handler.rs index fb8507228..21f4dd736 100644 --- a/pumpkin-inventory/src/screen_handler.rs +++ b/pumpkin-inventory/src/screen_handler.rs @@ -41,18 +41,19 @@ pub struct ScreenProperty { impl ScreenProperty { pub fn new(value: Arc, index: u8) -> Self { Self { - old_value: value.get_property(index as i32), + old_value: value.get_property(i32::from(index)), index, value, } } + #[must_use] pub fn get(&self) -> i32 { - self.value.get_property(self.index as i32) + self.value.get_property(i32::from(self.index)) } pub fn set(&mut self, value: i32) { - self.value.set_property(self.index as i32, value); + self.value.set_property(i32::from(self.index), value); } pub fn has_changed(&mut self) -> bool { @@ -66,7 +67,7 @@ impl ScreenProperty { pub type PlayerFuture<'a, T> = Pin + Send + 'a>>; pub trait InventoryPlayer: Send + Sync { - fn drop_item<'a>(&'a self, item: ItemStack, retain_ownership: bool) -> PlayerFuture<'a, ()>; + fn drop_item(&self, item: ItemStack, retain_ownership: bool) -> PlayerFuture<'_, ()>; fn get_inventory(&self) -> Arc; fn has_infinite_materials(&self) -> bool; @@ -238,10 +239,10 @@ pub trait ScreenHandler: Send + Sync { }) } - fn copy_shared_slots<'a>( - &'a mut self, + fn copy_shared_slots( + &mut self, other: Arc>, - ) -> ScreenHandlerFuture<'a, ()> { + ) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let mut table: HashMap> = HashMap::new(); let other_binding = other.lock().await; @@ -274,7 +275,7 @@ pub trait ScreenHandler: Send + Sync { }) } - fn sync_state<'a>(&'a mut self) -> ScreenHandlerFuture<'a, ()> { + fn sync_state(&mut self) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let behaviour = self.get_behaviour_mut(); let mut previous_tracked_stacks = Vec::new(); @@ -311,20 +312,20 @@ pub trait ScreenHandler: Send + Sync { }) } - fn add_listener<'a>( - &'a mut self, + fn add_listener( + &mut self, listener: Arc, - ) -> ScreenHandlerFuture<'a, ()> { + ) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { self.get_behaviour_mut().listeners.push(listener); self.send_content_updates().await; }) } - fn update_sync_handler<'a>( - &'a mut self, + fn update_sync_handler( + &mut self, sync_handler: Arc, - ) -> ScreenHandlerFuture<'a, ()> { + ) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let behaviour = self.get_behaviour_mut(); behaviour.sync_handler = Some(sync_handler.clone()); @@ -332,7 +333,7 @@ pub trait ScreenHandler: Send + Sync { }) } - fn update_to_client<'a>(&'a mut self) -> ScreenHandlerFuture<'a, ()> { + fn update_to_client(&mut self) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { for i in 0..self.get_behaviour().slots.len() { let behaviour = self.get_behaviour_mut(); @@ -359,16 +360,12 @@ pub trait ScreenHandler: Send + Sync { }) } - fn update_tracked_properties<'a>( - &'a mut self, - idx: i32, - value: i32, - ) -> ScreenHandlerFuture<'a, ()> { + fn update_tracked_properties(&mut self, idx: i32, value: i32) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let behaviour = self.get_behaviour_mut(); if idx <= behaviour.tracked_property_values.len() as i32 { behaviour.tracked_property_values[idx as usize] = value; - for listener in behaviour.listeners.iter() { + for listener in &behaviour.listeners { listener .on_property_update(behaviour, idx as u8, value) .await; @@ -377,11 +374,7 @@ pub trait ScreenHandler: Send + Sync { }) } - fn check_property_updates<'a>( - &'a mut self, - idx: i32, - value: i32, - ) -> ScreenHandlerFuture<'a, ()> { + fn check_property_updates(&mut self, idx: i32, value: i32) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let behaviour = self.get_behaviour_mut(); if !behaviour.disable_sync @@ -400,18 +393,18 @@ pub trait ScreenHandler: Send + Sync { }) } - fn update_tracked_slot<'a>( - &'a mut self, + fn update_tracked_slot( + &mut self, slot: usize, stack: ItemStack, - ) -> ScreenHandlerFuture<'a, ()> { + ) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let behaviour = self.get_behaviour_mut(); let other_stack = &behaviour.tracked_stacks[slot]; if !other_stack.are_equal(&stack) { behaviour.tracked_stacks[slot] = stack.clone(); - for listener in behaviour.listeners.iter() { + for listener in &behaviour.listeners { listener .on_slot_update(behaviour, slot as u8, stack.clone()) .await; @@ -420,11 +413,7 @@ pub trait ScreenHandler: Send + Sync { }) } - fn check_slot_updates<'a>( - &'a mut self, - slot: usize, - stack: ItemStack, - ) -> ScreenHandlerFuture<'a, ()> { + fn check_slot_updates(&mut self, slot: usize, stack: ItemStack) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let behaviour = self.get_behaviour_mut(); if !behaviour.disable_sync { @@ -443,7 +432,7 @@ pub trait ScreenHandler: Send + Sync { }) } - fn check_cursor_stack_updates<'a>(&'a mut self) -> ScreenHandlerFuture<'a, ()> { + fn check_cursor_stack_updates(&mut self) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let behaviour = self.get_behaviour_mut(); if !behaviour.disable_sync { @@ -462,7 +451,7 @@ pub trait ScreenHandler: Send + Sync { }) } - fn send_content_updates<'a>(&'a mut self) -> ScreenHandlerFuture<'a, ()> { + fn send_content_updates(&mut self) -> ScreenHandlerFuture<'_, ()> { Box::pin(async move { let slots_len = self.get_behaviour().slots.len(); @@ -492,7 +481,7 @@ pub trait ScreenHandler: Send + Sync { }) } - fn is_slot_valid<'a>(&'a self, slot: i32) -> ScreenHandlerFuture<'a, bool> { + fn is_slot_valid(&self, slot: i32) -> ScreenHandlerFuture<'_, bool> { Box::pin(async move { slot == -1 || slot == -999 || slot < self.get_behaviour().slots.len() as i32 }) @@ -645,6 +634,7 @@ pub trait ScreenHandler: Send + Sync { }) } + #[expect(clippy::too_many_lines)] fn internal_on_slot_click<'a>( &'a mut self, slot_index: i32, @@ -658,7 +648,7 @@ pub trait ScreenHandler: Send + Sync { let mut cursor_stack = behavior.cursor_stack.lock().await; let mut to_pick_up = cursor_stack.get_max_stack_size() - cursor_stack.item_count; - for slot in behavior.slots.iter() { + for slot in &behavior.slots { if to_pick_up == 0 { break; } @@ -727,7 +717,7 @@ pub trait ScreenHandler: Send + Sync { let mut cursor_stack = behaviour.cursor_stack.lock().await; let initial_count = cursor_stack.item_count; - for slot_index in behaviour.drag_slots.iter() { + for slot_index in &behaviour.drag_slots { let slot = behaviour.slots[*slot_index as usize].clone(); let stack_lock = slot.get_stack().await; let stack = stack_lock.lock().await; @@ -1070,6 +1060,7 @@ pub struct ScreenHandlerBehaviour { } impl ScreenHandlerBehaviour { + #[must_use] pub fn new(sync_id: u8, window_type: Option) -> Self { Self { slots: Vec::new(), diff --git a/pumpkin-inventory/src/slot.rs b/pumpkin-inventory/src/slot.rs index 9d333d40a..cca5e470d 100644 --- a/pumpkin-inventory/src/slot.rs +++ b/pumpkin-inventory/src/slot.rs @@ -232,9 +232,7 @@ pub trait Slot: Send + Sync { .min(stack.item_count) .min(self.get_max_item_count_for_stack(&stack).await - stack_self.item_count); - if min_count == 0 { - stack - } else { + if min_count != 0 { if stack_self.is_empty() { drop(stack_self); self.set_stack(stack.split(min_count)).await; @@ -245,12 +243,9 @@ pub trait Slot: Send + Sync { drop(stack_self); self.set_stack(cloned_stack).await; } - - stack } - } else { - stack } + stack }) } } diff --git a/pumpkin-inventory/src/sync_handler.rs b/pumpkin-inventory/src/sync_handler.rs index 818a35cfb..ef6140fad 100644 --- a/pumpkin-inventory/src/sync_handler.rs +++ b/pumpkin-inventory/src/sync_handler.rs @@ -25,6 +25,7 @@ impl Default for SyncHandler { } impl SyncHandler { + #[must_use] pub fn new() -> Self { Self { player: Mutex::new(None), @@ -128,7 +129,7 @@ pub struct TrackedStack { } impl TrackedStack { - pub const EMPTY: TrackedStack = TrackedStack { + pub const EMPTY: Self = Self { received_stack: None, received_hash: None, }; diff --git a/pumpkin-inventory/src/window_property.rs b/pumpkin-inventory/src/window_property.rs index 8d075255c..5996ecf25 100644 --- a/pumpkin-inventory/src/window_property.rs +++ b/pumpkin-inventory/src/window_property.rs @@ -36,14 +36,16 @@ pub enum EnchantmentTable { // TODO: No more magic numbers impl WindowPropertyTrait for EnchantmentTable { fn to_id(self) -> i16 { - use EnchantmentTable::*; + use EnchantmentTable::{ + EnchantmentId, EnchantmentLevel, EnchantmentSeed, LevelRequirement, + }; - (match self { + i16::from(match self { LevelRequirement { slot } => slot, EnchantmentSeed => 3, EnchantmentId { slot } => 4 + slot, EnchantmentLevel { slot } => 7 + slot, - }) as i16 + }) } } pub enum Beacon { diff --git a/pumpkin-macros/Cargo.toml b/pumpkin-macros/Cargo.toml index aa42a1adf..4756fb5c8 100644 --- a/pumpkin-macros/Cargo.toml +++ b/pumpkin-macros/Cargo.toml @@ -15,3 +15,6 @@ pumpkin-data.workspace = true proc-macro2.workspace = true quote.workspace = true syn.workspace = true + +[lints] +workspace = true \ No newline at end of file diff --git a/pumpkin-macros/src/lib.rs b/pumpkin-macros/src/lib.rs index 1bcce45ea..32e6e8b23 100644 --- a/pumpkin-macros/src/lib.rs +++ b/pumpkin-macros/src/lib.rs @@ -46,7 +46,7 @@ pub fn cancellable(_args: TokenStream, input: TokenStream) -> TokenStream { if fields .named .iter() - .any(|f| f.ident.as_ref().map(|i| i == "cancelled").unwrap_or(false)) + .any(|f| f.ident.as_ref().is_some_and(|i| i == "cancelled")) { abort!(fields.span(), "Struct already has a `cancelled` field"); } @@ -199,13 +199,10 @@ pub fn pumpkin_block(args: TokenStream, item: TokenStream) -> TokenStream { let arg_value = arg_lit.value(); let block_name = arg_value.strip_prefix("minecraft:").unwrap_or(&arg_value); - let block = match Block::from_name(block_name) { - Some(b) => b, - None => { - return syn::Error::new(arg_lit.span(), "Invalid block name") - .to_compile_error() - .into(); - } + let Some(block) = Block::from_name(block_name) else { + return syn::Error::new(arg_lit.span(), "Invalid block name") + .to_compile_error() + .into(); }; let block_id = block.id; @@ -239,16 +236,10 @@ pub fn pumpkin_block_from_tag(args: TokenStream, item: TokenStream) -> TokenStre let full_tag = arg_lit.value(); - let values = match get_tag_ids(RegistryKey::Block, &full_tag) { - Some(v) => v, - None => { - return syn::Error::new( - arg_lit.span(), - format!("Failed to get tag IDs: {}", full_tag), - ) + let Some(values) = get_tag_ids(RegistryKey::Block, &full_tag) else { + return syn::Error::new(arg_lit.span(), format!("Failed to get tag IDs: {full_tag}")) .to_compile_error() .into(); - } }; let expanded = quote! { @@ -522,7 +513,7 @@ fn check_serial_attributes(attrs: &[Attribute]) -> (bool, bool) { let mut is_big_endian = false; let mut no_prefix = false; - for attr in attrs.iter() { + for attr in attrs { if attr.path().is_ident("serial") { let _ = attr.parse_nested_meta(|meta| { if meta.path.is_ident("big_endian") { @@ -545,8 +536,7 @@ fn is_vec(ty: &Type) -> bool { .segments .iter() .last() - .map(|segment| segment.ident == "Vec") - .unwrap_or(false) + .is_some_and(|segment| segment.ident == "Vec") } else { false } diff --git a/pumpkin-nbt/Cargo.toml b/pumpkin-nbt/Cargo.toml index 90e5fec52..bf9db3b70 100644 --- a/pumpkin-nbt/Cargo.toml +++ b/pumpkin-nbt/Cargo.toml @@ -14,3 +14,6 @@ flate2.workspace = true [dev-dependencies] tempfile.workspace = true + +[lints] +workspace = true diff --git a/pumpkin-nbt/src/compound.rs b/pumpkin-nbt/src/compound.rs index 70de471fe..be3050baa 100644 --- a/pumpkin-nbt/src/compound.rs +++ b/pumpkin-nbt/src/compound.rs @@ -20,8 +20,9 @@ pub struct NbtCompound { } impl NbtCompound { - pub fn new() -> NbtCompound { - NbtCompound { + #[must_use] + pub fn new() -> Self { + Self { child_tags: Vec::new(), } } @@ -39,7 +40,7 @@ impl NbtCompound { } let len = reader.get_u16_be()?; - reader.skip_bytes(len as i64)?; + reader.skip_bytes(i64::from(len))?; // Skip Value NbtTag::skip_data(reader, tag_id)?; @@ -50,8 +51,8 @@ impl NbtCompound { pub fn deserialize_content( reader: &mut NbtReadHelper, - ) -> Result { - let mut compound = NbtCompound::new(); + ) -> Result { + let mut compound = Self::new(); loop { let tag_id = match reader.get_u8_be() { @@ -83,6 +84,7 @@ impl NbtCompound { Ok(()) } + #[must_use] pub fn is_empty(&self) -> bool { self.child_tags.is_empty() } @@ -106,7 +108,7 @@ impl NbtCompound { } pub fn put_bool(&mut self, name: &str, value: bool) { - self.put(name, NbtTag::Byte(if value { 1 } else { 0 })); + self.put(name, NbtTag::Byte(i8::from(value))); } pub fn put_short(&mut self, name: &str, value: i16) { @@ -128,15 +130,17 @@ impl NbtCompound { self.put(name, NbtTag::Double(value)); } - pub fn put_component(&mut self, name: &str, value: NbtCompound) { + pub fn put_component(&mut self, name: &str, value: Self) { self.put(name, NbtTag::Compound(value)); } + #[must_use] pub fn get_byte(&self, name: &str) -> Option { - self.get(name).and_then(|tag| tag.extract_byte()) + self.get(name).and_then(super::tag::NbtTag::extract_byte) } #[inline] + #[must_use] pub fn get(&self, name: &str) -> Option<&NbtTag> { self.child_tags .iter() @@ -144,46 +148,57 @@ impl NbtCompound { .map(|r| &r.1) } + #[must_use] pub fn get_short(&self, name: &str) -> Option { - self.get(name).and_then(|tag| tag.extract_short()) + self.get(name).and_then(super::tag::NbtTag::extract_short) } + #[must_use] pub fn get_int(&self, name: &str) -> Option { - self.get(name).and_then(|tag| tag.extract_int()) + self.get(name).and_then(super::tag::NbtTag::extract_int) } + #[must_use] pub fn get_long(&self, name: &str) -> Option { - self.get(name).and_then(|tag| tag.extract_long()) + self.get(name).and_then(super::tag::NbtTag::extract_long) } + #[must_use] pub fn get_float(&self, name: &str) -> Option { - self.get(name).and_then(|tag| tag.extract_float()) + self.get(name).and_then(super::tag::NbtTag::extract_float) } + #[must_use] pub fn get_double(&self, name: &str) -> Option { - self.get(name).and_then(|tag| tag.extract_double()) + self.get(name).and_then(super::tag::NbtTag::extract_double) } + #[must_use] pub fn get_bool(&self, name: &str) -> Option { - self.get(name).and_then(|tag| tag.extract_bool()) + self.get(name).and_then(super::tag::NbtTag::extract_bool) } + #[must_use] pub fn get_string(&self, name: &str) -> Option<&str> { self.get(name).and_then(|tag| tag.extract_string()) } + #[must_use] pub fn get_list(&self, name: &str) -> Option<&[NbtTag]> { self.get(name).and_then(|tag| tag.extract_list()) } - pub fn get_compound(&self, name: &str) -> Option<&NbtCompound> { + #[must_use] + pub fn get_compound(&self, name: &str) -> Option<&Self> { self.get(name).and_then(|tag| tag.extract_compound()) } + #[must_use] pub fn get_int_array(&self, name: &str) -> Option<&[i32]> { self.get(name).and_then(|tag| tag.extract_int_array()) } + #[must_use] pub fn get_long_array(&self, name: &str) -> Option<&[i64]> { self.get(name).and_then(|tag| tag.extract_long_array()) } @@ -197,7 +212,7 @@ impl From for NbtCompound { impl FromIterator<(String, NbtTag)> for NbtCompound { fn from_iter>(iter: T) -> Self { - let mut compound = NbtCompound::new(); + let mut compound = Self::new(); for (key, value) in iter { compound.put(&key, value); } @@ -216,13 +231,13 @@ impl IntoIterator for NbtCompound { impl Extend<(String, NbtTag)> for NbtCompound { fn extend>(&mut self, iter: T) { - self.child_tags.extend(iter) + self.child_tags.extend(iter); } } // Rust's AsRef is currently not reflexive so we need to implement it manually -impl AsRef for NbtCompound { - fn as_ref(&self) -> &NbtCompound { +impl AsRef for NbtCompound { + fn as_ref(&self) -> &Self { self } } @@ -267,11 +282,11 @@ impl<'de> Deserialize<'de> for NbtCompound { impl From for NbtTag { fn from(value: NbtCompound) -> Self { - NbtTag::Compound(value) + Self::Compound(value) } } -/// SNBT display implementation for NbtCompound +/// SNBT display implementation for `NbtCompound` impl Display for NbtCompound { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str("{")?; @@ -279,7 +294,7 @@ impl Display for NbtCompound { if i > 0 { f.write_str(", ")?; } - write!(f, "{}: {}", key, value)?; + write!(f, "{key}: {value}")?; } f.write_str("}") } @@ -288,52 +303,52 @@ impl Display for NbtCompound { impl Display for NbtTag { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - NbtTag::End => Ok(()), - NbtTag::Byte(v) => write!(f, "{v}b"), - NbtTag::Short(v) => write!(f, "{v}s"), - NbtTag::Int(v) => write!(f, "{v}"), - NbtTag::Long(v) => write!(f, "{v}L"), - NbtTag::Float(v) => write!(f, "{v}f"), - NbtTag::Double(v) => write!(f, "{v}d"), - NbtTag::String(v) => write!(f, "\"{v}\""), // TODO: Proper escaping needed for robust SNBT - NbtTag::Compound(v) => write!(f, "{v}"), - NbtTag::ByteArray(v) => { + Self::End => Ok(()), + Self::Byte(v) => write!(f, "{v}b"), + Self::Short(v) => write!(f, "{v}s"), + Self::Int(v) => write!(f, "{v}"), + Self::Long(v) => write!(f, "{v}L"), + Self::Float(v) => write!(f, "{v}f"), + Self::Double(v) => write!(f, "{v}d"), + Self::String(v) => write!(f, "\"{v}\""), // TODO: Proper escaping needed for robust SNBT + Self::Compound(v) => write!(f, "{v}"), + Self::ByteArray(v) => { f.write_str("[B;")?; for (i, byte) in v.iter().enumerate() { if i > 0 { - f.write_str(",")? + f.write_str(",")?; } - write!(f, " {}b", byte)?; + write!(f, " {byte}b")?; } f.write_str("]") } - NbtTag::List(v) => { + Self::List(v) => { f.write_str("[")?; for (i, tag) in v.iter().enumerate() { if i > 0 { - f.write_str(", ")? + f.write_str(", ")?; } - write!(f, "{}", tag)?; + write!(f, "{tag}")?; } f.write_str("]") } - NbtTag::IntArray(v) => { + Self::IntArray(v) => { f.write_str("[I;")?; for (i, int) in v.iter().enumerate() { if i > 0 { - f.write_str(",")? + f.write_str(",")?; } - write!(f, " {}", int)?; + write!(f, " {int}")?; } f.write_str("]") } - NbtTag::LongArray(v) => { + Self::LongArray(v) => { f.write_str("[L;")?; for (i, long) in v.iter().enumerate() { if i > 0 { - f.write_str(",")? + f.write_str(",")?; } - write!(f, " {}L", long)?; + write!(f, " {long}L")?; } f.write_str("]") } diff --git a/pumpkin-nbt/src/deserializer.rs b/pumpkin-nbt/src/deserializer.rs index 904afb01e..f1d927ca4 100644 --- a/pumpkin-nbt/src/deserializer.rs +++ b/pumpkin-nbt/src/deserializer.rs @@ -1,7 +1,10 @@ use std::cell::RefCell; use std::io::{Seek, SeekFrom}; -use crate::*; +use crate::{ + BYTE_ARRAY_ID, BYTE_ID, COMPOUND_ID, END_ID, Error, INT_ARRAY_ID, INT_ID, LIST_ID, + LONG_ARRAY_ID, LONG_ID, NbtTag, get_nbt_string, io, +}; use io::Read; use serde::de::{self, DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, Visitor}; use serde::{Deserialize, forward_to_deserialize_any}; @@ -13,7 +16,7 @@ thread_local! { } pub(super) fn take_curr_visitor_seq_list_id() -> Option { - CURR_VISITOR_LIST_TYPE.with(|cell| cell.take()) + CURR_VISITOR_LIST_TYPE.with(std::cell::RefCell::take) } pub(super) fn set_curr_visitor_seq_list_id(tag: Option) { @@ -85,7 +88,7 @@ pub struct Deserializer { impl Deserializer { pub fn new(input: R, is_named: bool) -> Self { - Deserializer { + Self { input: NbtReadHelper { reader: input }, tag_to_deserialize_stack: None, in_list: false, @@ -230,8 +233,7 @@ impl<'de, R: Read + Seek> de::Deserializer<'de> for &mut Deserializer { if let Some(tag_id) = self.tag_to_deserialize_stack { if tag_id != COMPOUND_ID { return Err(Error::SerdeError(format!( - "Trying to deserialize a map without a compound ID (id {})", - tag_id + "Trying to deserialize a map without a compound ID (id {tag_id})" ))); } } else { diff --git a/pumpkin-nbt/src/lib.rs b/pumpkin-nbt/src/lib.rs index efaeaf81a..7e011c0eb 100644 --- a/pumpkin-nbt/src/lib.rs +++ b/pumpkin-nbt/src/lib.rs @@ -59,13 +59,13 @@ pub enum Error { impl ser::Error for Error { fn custom(msg: T) -> Self { - Error::SerdeError(msg.to_string()) + Self::SerdeError(msg.to_string()) } } impl de::Error for Error { fn custom(msg: T) -> Self { - Error::SerdeError(msg.to_string()) + Self::SerdeError(msg.to_string()) } } @@ -76,40 +76,42 @@ pub struct Nbt { } impl Nbt { + #[must_use] pub fn new(name: String, tag: NbtCompound) -> Self { - Nbt { + Self { name, root_tag: tag, } } - pub fn read(reader: &mut NbtReadHelper) -> Result { + pub fn read(reader: &mut NbtReadHelper) -> Result { let tag_type_id = reader.get_u8_be()?; if tag_type_id != COMPOUND_ID { return Err(Error::NoRootCompound(tag_type_id)); } - Ok(Nbt { + Ok(Self { name: get_nbt_string(reader)?, root_tag: NbtCompound::deserialize_content(reader)?, }) } /// Reads an NBT tag that doesn't contain the name of the root `Compound`. - pub fn read_unnamed(reader: &mut NbtReadHelper) -> Result { + pub fn read_unnamed(reader: &mut NbtReadHelper) -> Result { let tag_type_id = reader.get_u8_be()?; if tag_type_id != COMPOUND_ID { return Err(Error::NoRootCompound(tag_type_id)); } - Ok(Nbt { + Ok(Self { name: String::new(), root_tag: NbtCompound::deserialize_content(reader)?, }) } + #[must_use] pub fn write(self) -> Bytes { let mut bytes = Vec::new(); let mut writer = WriteAdaptor::new(&mut bytes); @@ -128,6 +130,7 @@ impl Nbt { } /// Writes an NBT tag without a root `Compound` name. + #[must_use] pub fn write_unnamed(self) -> Bytes { let mut bytes = Vec::new(); let mut writer = WriteAdaptor::new(&mut bytes); @@ -154,14 +157,14 @@ impl Deref for Nbt { impl From for Nbt { fn from(value: NbtCompound) -> Self { - Nbt::new(String::new(), value) + Self::new(String::new(), value) } } impl AsRef for Nbt where T: ?Sized, - ::Target: AsRef, + ::Target: AsRef, { fn as_ref(&self) -> &T { self.deref().as_ref() @@ -246,6 +249,7 @@ mod test { } #[derive(Serialize, Deserialize, PartialEq, Debug)] + #[expect(clippy::struct_field_names)] struct TestArray { #[serde(serialize_with = "nbt_byte_array")] byte_array: Vec, @@ -354,7 +358,7 @@ mod test { }, }, compounds: vec![test1, test2], - list_string: vec!["".to_string(), "abcbcbcbbc".to_string()], + list_string: vec![String::new(), "abcbcbcbbc".to_string()], empty: vec![], }; @@ -392,7 +396,7 @@ mod test { }, }, compounds: vec![test1, test2], - list_string: vec!["".to_string(), "abcbcbcbbc".to_string()], + list_string: vec![String::new(), "abcbcbcbbc".to_string()], empty: vec![], }; @@ -413,6 +417,12 @@ mod test { #[serde(serialize_with = "nbt_byte_array")] b: [u8; 1], } + #[derive(Serialize)] + struct NotTagged { + l: [i64; 1], + i: [i32; 1], + b: [u8; 1], + } let value = Tagged { l: [0], @@ -444,13 +454,6 @@ mod test { to_bytes(&value, &mut bytes).unwrap(); assert_eq!(bytes, expected_bytes); - #[derive(Serialize)] - struct NotTagged { - l: [i64; 1], - i: [i32; 1], - b: [u8; 1], - } - let value = NotTagged { l: [0], i: [0], @@ -499,7 +502,7 @@ mod test { match err { Err(Error::SerdeError(_)) => (), _ => panic!("Expected to fail serialization!"), - }; + } } #[test] diff --git a/pumpkin-nbt/src/nbt_compress.rs b/pumpkin-nbt/src/nbt_compress.rs index 3ddc2cf7a..42907c1b5 100644 --- a/pumpkin-nbt/src/nbt_compress.rs +++ b/pumpkin-nbt/src/nbt_compress.rs @@ -3,15 +3,15 @@ use crate::{Error, Nbt, NbtCompound, deserializer, serializer}; use flate2::{Compression, read::GzDecoder, write::GzEncoder}; use std::io::{Cursor, Read, Seek, Write}; -/// Reads a GZipped NBT compound tag from any reader. +/// Reads a `GZipped` NBT compound tag from any reader. /// /// # Arguments /// -/// * `input` - Any type implementing the Read trait containing GZipped NBT data +/// * `input` - Any type implementing the Read trait containing `GZipped` NBT data /// /// # Returns /// -/// A Result containing either the parsed NbtCompound or an Error +/// A Result containing either the parsed `NbtCompound` or an Error pub fn read_gzip_compound_tag(input: impl Read + Seek) -> Result { // Create a GZip decoder and directly chain it to the NBT reader let mut decoder = GzDecoder::new(input); @@ -24,13 +24,13 @@ pub fn read_gzip_compound_tag(input: impl Read + Seek) -> Result Result Ok(buffer) } -/// Reads a GZipped NBT structure into a Rust type. +/// Reads a `GZipped` NBT structure into a Rust type. /// /// # Arguments /// -/// * `input` - Any type implementing the Read trait containing GZipped NBT data +/// * `input` - Any type implementing the Read trait containing `GZipped` NBT data /// /// # Returns /// @@ -75,7 +75,7 @@ pub fn from_gzip_bytes<'a, T: serde::Deserialize<'a>, R: Read>(input: R) -> Resu deserializer::from_bytes(Cursor::new(buf)) } -/// Writes a Rust type as GZipped NBT to any writer. +/// Writes a Rust type as `GZipped` NBT to any writer. /// /// # Arguments /// @@ -262,6 +262,7 @@ mod tests { } #[test] + #[expect(clippy::print_stdout)] fn test_gzip_compression_ratio() { let mut compound = NbtCompound::new(); @@ -294,6 +295,7 @@ mod tests { } #[test] + #[expect(clippy::struct_field_names)] fn test_roundtrip_with_arrays() { #[derive(Serialize, Deserialize, Debug, PartialEq)] struct ArrayTest { diff --git a/pumpkin-nbt/src/serializer.rs b/pumpkin-nbt/src/serializer.rs index 1c652acec..af5ff9173 100644 --- a/pumpkin-nbt/src/serializer.rs +++ b/pumpkin-nbt/src/serializer.rs @@ -122,20 +122,19 @@ impl Serializer { return Err(Error::SerdeError( "Invalid state: already handled root component!".to_string(), )); - } else { - if tag != COMPOUND_ID { - return Err(Error::SerdeError(format!( - "Invalid state: root is not a `Compound`! ({tag})" - ))); - } - self.handled_root = true; - self.output.write_u8_be(tag)?; - if let Some(root_name) = root_name { - NbtTag::write_string(root_name, &mut self.output)?; - } + } + if tag != COMPOUND_ID { + return Err(Error::SerdeError(format!( + "Invalid state: root is not a `Compound`! ({tag})" + ))); + } + self.handled_root = true; + self.output.write_u8_be(tag)?; + if let Some(root_name) = root_name { + NbtTag::write_string(root_name, &mut self.output)?; } } - }; + } Ok(()) } } @@ -171,7 +170,7 @@ impl ser::Serializer for &mut Serializer { type SerializeStructVariant = Impossible<(), Error>; fn serialize_bool(self, v: bool) -> Result<()> { - self.serialize_i8(v as i8)?; + self.serialize_i8(i8::from(v))?; Ok(()) } @@ -200,15 +199,14 @@ impl ser::Serializer for &mut Serializer { } fn serialize_u8(self, v: u8) -> Result<()> { - match self.state { - State::Named(_) => Err(Error::UnsupportedType( + if let State::Named(_) = self.state { + Err(Error::UnsupportedType( "u8; NBT only supports signed values".to_string(), - )), - _ => { - self.parse_state(BYTE_ID)?; - self.output.write_u8_be(v)?; - Ok(()) - } + )) + } else { + self.parse_state(BYTE_ID)?; + self.output.write_u8_be(v)?; + Ok(()) } } @@ -336,35 +334,32 @@ impl ser::Serializer for &mut Serializer { return Err(Error::LargeLength(len)); } - match &mut self.state { - State::Array { array_type, .. } => { - let (id, expected_tag) = match *array_type { - NBT_BYTE_ARRAY_TAG => (BYTE_ARRAY_ID, BYTE_ID), - NBT_INT_ARRAY_TAG => (INT_ARRAY_ID, INT_ID), - NBT_LONG_ARRAY_TAG => (LONG_ARRAY_ID, LONG_ID), - _ => { - return Err(Error::SerdeError( - "Array supports only `byte`, `int`, and `long`".to_string(), - )); - } - }; - - self.parse_state(id)?; - self.output.write_i32_be(len as i32)?; - - // We can mark anything as an NBT array list, so mark as needed to be checked. - self.expected_list_tag = expected_tag; - self.state = State::CheckedListElement; - } - _ => { - self.parse_state(LIST_ID)?; - self.state = State::FirstListElement { len: len as i32 }; - if len == 0 { - // If we have no elements, the `FirstListElement` state will never be invoked, so - // write the (unknown) list type and length here. - self.output.write_u8_be(END_ID)?; - self.output.write_i32_be(0)?; + if let State::Array { array_type, .. } = &mut self.state { + let (id, expected_tag) = match *array_type { + NBT_BYTE_ARRAY_TAG => (BYTE_ARRAY_ID, BYTE_ID), + NBT_INT_ARRAY_TAG => (INT_ARRAY_ID, INT_ID), + NBT_LONG_ARRAY_TAG => (LONG_ARRAY_ID, LONG_ID), + _ => { + return Err(Error::SerdeError( + "Array supports only `byte`, `int`, and `long`".to_string(), + )); } + }; + + self.parse_state(id)?; + self.output.write_i32_be(len as i32)?; + + // We can mark anything as an NBT array list, so mark as needed to be checked. + self.expected_list_tag = expected_tag; + self.state = State::CheckedListElement; + } else { + self.parse_state(LIST_ID)?; + self.state = State::FirstListElement { len: len as i32 }; + if len == 0 { + // If we have no elements, the `FirstListElement` state will never be invoked, so + // write the (unknown) list type and length here. + self.output.write_u8_be(END_ID)?; + self.output.write_i32_be(0)?; } } diff --git a/pumpkin-nbt/src/tag.rs b/pumpkin-nbt/src/tag.rs index 740510e60..2741f28a0 100644 --- a/pumpkin-nbt/src/tag.rs +++ b/pumpkin-nbt/src/tag.rs @@ -4,7 +4,11 @@ use io::Read; use serde::{Deserialize, Serialize}; use serializer::WriteAdaptor; -use crate::*; +use crate::{ + BYTE_ARRAY_ID, BYTE_ID, COMPOUND_ID, DOUBLE_ID, END_ID, Error, FLOAT_ID, INT_ARRAY_ID, INT_ID, + LIST_ID, LONG_ARRAY_ID, LONG_ID, SHORT_ID, STRING_ID, Seek, Write, compound, deserializer, + get_nbt_string, io, nbt_byte_array, nbt_int_array, nbt_long_array, serializer, +}; #[derive(Clone, Debug, PartialEq, PartialOrd)] #[repr(u8)] @@ -18,7 +22,7 @@ pub enum NbtTag { Double(f64) = DOUBLE_ID, ByteArray(Box<[u8]>) = BYTE_ARRAY_ID, String(String) = STRING_ID, - List(Vec) = LIST_ID, + List(Vec) = LIST_ID, Compound(NbtCompound) = COMPOUND_ID, IntArray(Vec) = INT_ARRAY_ID, LongArray(Vec) = LONG_ARRAY_ID, @@ -26,10 +30,11 @@ pub enum NbtTag { impl NbtTag { /// Returns the numeric id associated with the data type. + #[must_use] pub const fn get_type_id(&self) -> u8 { // Safety: Since Self is repr(u8), it is guaranteed to hold the discriminant in the first byte // See https://doc.rust-lang.org/reference/items/enumerations.html#pointer-casting - unsafe { *(self as *const Self as *const u8) } + unsafe { *std::ptr::from_ref::(self).cast::() } } pub fn serialize(self, w: &mut WriteAdaptor) -> serializer::Result<()> { @@ -52,14 +57,14 @@ impl NbtTag { pub fn serialize_data(self, w: &mut WriteAdaptor) -> serializer::Result<()> { match self { - NbtTag::End => {} - NbtTag::Byte(byte) => w.write_i8_be(byte)?, - NbtTag::Short(short) => w.write_i16_be(short)?, - NbtTag::Int(int) => w.write_i32_be(int)?, - NbtTag::Long(long) => w.write_i64_be(long)?, - NbtTag::Float(float) => w.write_f32_be(float)?, - NbtTag::Double(double) => w.write_f64_be(double)?, - NbtTag::ByteArray(byte_array) => { + Self::End => {} + Self::Byte(byte) => w.write_i8_be(byte)?, + Self::Short(short) => w.write_i16_be(short)?, + Self::Int(int) => w.write_i32_be(int)?, + Self::Long(long) => w.write_i64_be(long)?, + Self::Float(float) => w.write_f32_be(float)?, + Self::Double(double) => w.write_f64_be(double)?, + Self::ByteArray(byte_array) => { let len = byte_array.len(); if len > i32::MAX as usize { return Err(Error::LargeLength(len)); @@ -68,25 +73,25 @@ impl NbtTag { w.write_i32_be(len as i32)?; w.write_slice(&byte_array)?; } - NbtTag::String(string) => { + Self::String(string) => { Self::write_string(&string, w)?; } - NbtTag::List(list) => { + Self::List(list) => { let len = list.len(); if len > i32::MAX as usize { return Err(Error::LargeLength(len)); } - w.write_u8_be(list.first().unwrap_or(&NbtTag::End).get_type_id())?; + w.write_u8_be(list.first().unwrap_or(&Self::End).get_type_id())?; w.write_i32_be(len as i32)?; for nbt_tag in list { nbt_tag.serialize_data(w)?; } } - NbtTag::Compound(compound) => { + Self::Compound(compound) => { compound.serialize_content(w)?; } - NbtTag::IntArray(int_array) => { + Self::IntArray(int_array) => { let len = int_array.len(); if len > i32::MAX as usize { return Err(Error::LargeLength(len)); @@ -97,7 +102,7 @@ impl NbtTag { w.write_i32_be(int)?; } } - NbtTag::LongArray(long_array) => { + Self::LongArray(long_array) => { let len = long_array.len(); if len > i32::MAX as usize { return Err(Error::LargeLength(len)); @@ -109,11 +114,11 @@ impl NbtTag { w.write_i64_be(long)?; } } - }; + } Ok(()) } - pub fn deserialize(reader: &mut NbtReadHelper) -> Result { + pub fn deserialize(reader: &mut NbtReadHelper) -> Result { let tag_id = reader.get_u8_be()?; Self::deserialize_data(reader, tag_id) } @@ -126,20 +131,18 @@ impl NbtTag { END_ID => Ok(()), BYTE_ID => reader.skip_bytes(1), SHORT_ID => reader.skip_bytes(2), - INT_ID => reader.skip_bytes(4), - LONG_ID => reader.skip_bytes(8), - FLOAT_ID => reader.skip_bytes(4), - DOUBLE_ID => reader.skip_bytes(8), + INT_ID | FLOAT_ID => reader.skip_bytes(4), + LONG_ID | DOUBLE_ID => reader.skip_bytes(8), BYTE_ARRAY_ID => { let len = reader.get_i32_be()?; if len < 0 { return Err(Error::NegativeLength(len)); } - reader.skip_bytes(len as i64) + reader.skip_bytes(i64::from(len)) } STRING_ID => { let len = reader.get_u16_be()?; - reader.skip_bytes(len as i64) + reader.skip_bytes(i64::from(len)) } LIST_ID => { let tag_type_id = reader.get_u8_be()?; @@ -161,7 +164,7 @@ impl NbtTag { return Err(Error::NegativeLength(len)); } - reader.skip_bytes(len as i64 * 4) + reader.skip_bytes(i64::from(len) * 4) } LONG_ARRAY_ID => { let len = reader.get_i32_be()?; @@ -169,7 +172,7 @@ impl NbtTag { return Err(Error::NegativeLength(len)); } - reader.skip_bytes(len as i64 * 8) + reader.skip_bytes(i64::from(len) * 8) } _ => Err(Error::UnknownTagId(tag_id)), } @@ -178,32 +181,32 @@ impl NbtTag { pub fn deserialize_data( reader: &mut NbtReadHelper, tag_id: u8, - ) -> Result { + ) -> Result { match tag_id { - END_ID => Ok(NbtTag::End), + END_ID => Ok(Self::End), BYTE_ID => { let byte = reader.get_i8_be()?; - Ok(NbtTag::Byte(byte)) + Ok(Self::Byte(byte)) } SHORT_ID => { let short = reader.get_i16_be()?; - Ok(NbtTag::Short(short)) + Ok(Self::Short(short)) } INT_ID => { let int = reader.get_i32_be()?; - Ok(NbtTag::Int(int)) + Ok(Self::Int(int)) } LONG_ID => { let long = reader.get_i64_be()?; - Ok(NbtTag::Long(long)) + Ok(Self::Long(long)) } FLOAT_ID => { let float = reader.get_f32_be()?; - Ok(NbtTag::Float(float)) + Ok(Self::Float(float)) } DOUBLE_ID => { let double = reader.get_f64_be()?; - Ok(NbtTag::Double(double)) + Ok(Self::Double(double)) } BYTE_ARRAY_ID => { let len = reader.get_i32_be()?; @@ -212,9 +215,9 @@ impl NbtTag { } let byte_array = reader.read_boxed_slice(len as usize)?; - Ok(NbtTag::ByteArray(byte_array)) + Ok(Self::ByteArray(byte_array)) } - STRING_ID => Ok(NbtTag::String(get_nbt_string(reader)?)), + STRING_ID => Ok(Self::String(get_nbt_string(reader)?)), LIST_ID => { let tag_type_id = reader.get_u8_be()?; let len = reader.get_i32_be()?; @@ -224,13 +227,13 @@ impl NbtTag { let mut list = Vec::with_capacity(len as usize); for _ in 0..len { - let tag = NbtTag::deserialize_data(reader, tag_type_id)?; + let tag = Self::deserialize_data(reader, tag_type_id)?; assert_eq!(tag.get_type_id(), tag_type_id); list.push(tag); } - Ok(NbtTag::List(list)) + Ok(Self::List(list)) } - COMPOUND_ID => Ok(NbtTag::Compound(NbtCompound::deserialize_content(reader)?)), + COMPOUND_ID => Ok(Self::Compound(NbtCompound::deserialize_content(reader)?)), INT_ARRAY_ID => { let len = reader.get_i32_be()?; if len < 0 { @@ -243,7 +246,7 @@ impl NbtTag { let int = reader.get_i32_be()?; int_array.push(int); } - Ok(NbtTag::IntArray(int_array)) + Ok(Self::IntArray(int_array)) } LONG_ARRAY_ID => { let len = reader.get_i32_be()?; @@ -257,99 +260,112 @@ impl NbtTag { let long = reader.get_i64_be()?; long_array.push(long); } - Ok(NbtTag::LongArray(long_array)) + Ok(Self::LongArray(long_array)) } _ => Err(Error::UnknownTagId(tag_id)), } } + #[must_use] pub fn extract_byte(&self) -> Option { match self { - NbtTag::Byte(byte) => Some(*byte), + Self::Byte(byte) => Some(*byte), _ => None, } } + #[must_use] pub fn extract_short(&self) -> Option { match self { - NbtTag::Short(short) => Some(*short), + Self::Short(short) => Some(*short), _ => None, } } + #[must_use] pub fn extract_int(&self) -> Option { match self { - NbtTag::Int(int) => Some(*int), + Self::Int(int) => Some(*int), _ => None, } } + #[must_use] pub fn extract_long(&self) -> Option { match self { - NbtTag::Long(long) => Some(*long), + Self::Long(long) => Some(*long), _ => None, } } + #[must_use] pub fn extract_float(&self) -> Option { match self { - NbtTag::Float(float) => Some(*float), + Self::Float(float) => Some(*float), _ => None, } } + #[must_use] pub fn extract_double(&self) -> Option { match self { - NbtTag::Double(double) => Some(*double), + Self::Double(double) => Some(*double), _ => None, } } + #[must_use] pub fn extract_bool(&self) -> Option { match self { - NbtTag::Byte(byte) => Some(byte != &0), + Self::Byte(byte) => Some(byte != &0), _ => None, } } + #[must_use] pub fn extract_byte_array(&self) -> Option<&[u8]> { match self { - NbtTag::ByteArray(byte_array) => Some(byte_array), + Self::ByteArray(byte_array) => Some(byte_array), _ => None, } } + #[must_use] pub fn extract_string(&self) -> Option<&str> { match self { - NbtTag::String(string) => Some(string), + Self::String(string) => Some(string), _ => None, } } - pub fn extract_list(&self) -> Option<&[NbtTag]> { + #[must_use] + pub fn extract_list(&self) -> Option<&[Self]> { match self { - NbtTag::List(list) => Some(list), + Self::List(list) => Some(list), _ => None, } } + #[must_use] pub fn extract_compound(&self) -> Option<&NbtCompound> { match self { - NbtTag::Compound(compound) => Some(compound), + Self::Compound(compound) => Some(compound), _ => None, } } + #[must_use] pub fn extract_int_array(&self) -> Option<&[i32]> { match self { - NbtTag::IntArray(int_array) => Some(int_array), + Self::IntArray(int_array) => Some(int_array), _ => None, } } + #[must_use] pub fn extract_long_array(&self) -> Option<&[i64]> { match self { - NbtTag::LongArray(long_array) => Some(long_array), + Self::LongArray(long_array) => Some(long_array), _ => None, } } @@ -357,7 +373,7 @@ impl NbtTag { impl From<&str> for NbtTag { fn from(value: &str) -> Self { - NbtTag::String(value.to_string()) + Self::String(value.to_string()) } } @@ -365,51 +381,51 @@ impl From<&[u8]> for NbtTag { fn from(value: &[u8]) -> Self { let mut cloned = Vec::with_capacity(value.len()); cloned.copy_from_slice(value); - NbtTag::ByteArray(cloned.into_boxed_slice()) + Self::ByteArray(cloned.into_boxed_slice()) } } impl From for NbtTag { fn from(value: f32) -> Self { - NbtTag::Float(value) + Self::Float(value) } } impl From for NbtTag { fn from(value: f64) -> Self { - NbtTag::Double(value) + Self::Double(value) } } impl From for NbtTag { fn from(value: bool) -> Self { - NbtTag::Byte(value as i8) + Self::Byte(i8::from(value)) } } impl Serialize for NbtTag { fn serialize(&self, serializer: S) -> Result { match self { - NbtTag::End => serializer.serialize_unit(), - NbtTag::Byte(v) => serializer.serialize_i8(*v), - NbtTag::Short(v) => serializer.serialize_i16(*v), - NbtTag::Int(v) => serializer.serialize_i32(*v), - NbtTag::Long(v) => serializer.serialize_i64(*v), - NbtTag::Float(v) => serializer.serialize_f32(*v), - NbtTag::Double(v) => serializer.serialize_f64(*v), - NbtTag::ByteArray(v) => nbt_byte_array(v, serializer), - NbtTag::String(v) => serializer.serialize_str(v), - NbtTag::List(v) => { + Self::End => serializer.serialize_unit(), + Self::Byte(v) => serializer.serialize_i8(*v), + Self::Short(v) => serializer.serialize_i16(*v), + Self::Int(v) => serializer.serialize_i32(*v), + Self::Long(v) => serializer.serialize_i64(*v), + Self::Float(v) => serializer.serialize_f32(*v), + Self::Double(v) => serializer.serialize_f64(*v), + Self::ByteArray(v) => nbt_byte_array(v, serializer), + Self::String(v) => serializer.serialize_str(v), + Self::List(v) => { use serde::ser::SerializeSeq; let mut seq = serializer.serialize_seq(Some(v.len()))?; - for item in v.iter() { + for item in v { seq.serialize_element(item)?; } seq.end() } - NbtTag::Compound(v) => v.serialize(serializer), - NbtTag::IntArray(v) => nbt_int_array(v, serializer), - NbtTag::LongArray(v) => nbt_long_array(v, serializer), + Self::Compound(v) => v.serialize(serializer), + Self::IntArray(v) => nbt_int_array(v, serializer), + Self::LongArray(v) => nbt_long_array(v, serializer), } } } @@ -426,7 +442,7 @@ impl<'de> Deserialize<'de> for NbtTag { } fn visit_bool(self, v: bool) -> Result { - Ok(NbtTag::Byte(v as i8)) + Ok(NbtTag::Byte(i8::from(v))) } fn visit_i8(self, v: i8) -> Result { @@ -493,8 +509,7 @@ impl<'de> Deserialize<'de> for NbtTag { Ok(NbtTag::List(vec)) } _ => Err(serde::de::Error::custom(format!( - "Invalid list type id: {}", - curr + "Invalid list type id: {curr}" ))), } } diff --git a/pumpkin-protocol/Cargo.toml b/pumpkin-protocol/Cargo.toml index 205594af5..c2cc2f1df 100644 --- a/pumpkin-protocol/Cargo.toml +++ b/pumpkin-protocol/Cargo.toml @@ -36,3 +36,6 @@ bitflags.workspace = true [dev-dependencies] # Validate correctness flate2.workspace = true + +[lints] +workspace = true diff --git a/pumpkin-protocol/src/bedrock/ack.rs b/pumpkin-protocol/src/bedrock/ack.rs index 0b0ce9c0a..6fe2f0643 100644 --- a/pumpkin-protocol/src/bedrock/ack.rs +++ b/pumpkin-protocol/src/bedrock/ack.rs @@ -15,6 +15,7 @@ pub struct Ack { } impl Ack { + #[must_use] pub fn new(sequences: Vec) -> Self { Self { sequences } } @@ -65,14 +66,12 @@ impl Ack { let mut start = self.sequences[0]; let mut end = start; for seq in self.sequences.iter().copied() { - if seq == end + 1 { - end = seq - } else { + if seq != end + 1 { Self::write_range(start, end, &mut buf)?; count += 1; start = seq; - end = seq; } + end = seq; } Self::write_range(start, end, &mut buf)?; count += 1; diff --git a/pumpkin-protocol/src/bedrock/client/disconnect_player.rs b/pumpkin-protocol/src/bedrock/client/disconnect_player.rs index 306c38247..79e5a0a3d 100644 --- a/pumpkin-protocol/src/bedrock/client/disconnect_player.rs +++ b/pumpkin-protocol/src/bedrock/client/disconnect_player.rs @@ -13,6 +13,7 @@ pub struct CDisconnectPlayer { } impl CDisconnectPlayer { + #[must_use] pub fn new(reason: i32, message: String) -> Self { Self { reason: VarInt(reason), diff --git a/pumpkin-protocol/src/bedrock/client/handshake.rs b/pumpkin-protocol/src/bedrock/client/handshake.rs index 0dd5a1256..116a4b30c 100644 --- a/pumpkin-protocol/src/bedrock/client/handshake.rs +++ b/pumpkin-protocol/src/bedrock/client/handshake.rs @@ -8,6 +8,7 @@ pub struct CHandshake { } impl CHandshake { + #[must_use] pub fn new(jwt_data: String) -> Self { Self { jwt_data } } diff --git a/pumpkin-protocol/src/bedrock/client/inventory_content.rs b/pumpkin-protocol/src/bedrock/client/inventory_content.rs index 6d21cc39b..c9e46dcd4 100644 --- a/pumpkin-protocol/src/bedrock/client/inventory_content.rs +++ b/pumpkin-protocol/src/bedrock/client/inventory_content.rs @@ -13,6 +13,6 @@ pub struct CInventoryContent { pub slots: Vec, pub container_name: u8, pub dynamic_id: Option, - /// Use NetworkItemDescriptor if none + /// Use `NetworkItemDescriptor` if none pub storage_item: NetworkItemStackDescriptor, } diff --git a/pumpkin-protocol/src/bedrock/client/level_chunk.rs b/pumpkin-protocol/src/bedrock/client/level_chunk.rs index 7eac01b8c..114be5e30 100644 --- a/pumpkin-protocol/src/bedrock/client/level_chunk.rs +++ b/pumpkin-protocol/src/bedrock/client/level_chunk.rs @@ -20,7 +20,7 @@ pub struct CLevelChunk<'a> { pub chunk: &'a ChunkData, } -impl<'a> PacketWrite for CLevelChunk<'a> { +impl PacketWrite for CLevelChunk<'_> { fn write(&self, writer: &mut W) -> Result<(), Error> { VarInt(self.chunk.x).write(writer)?; VarInt(self.chunk.z).write(writer)?; @@ -52,12 +52,12 @@ impl<'a> PacketWrite for CLevelChunk<'a> { match network_repr.palette { NetworkPalette::Single(id) => { - VarInt(id as i32).write(data_write)?; + VarInt(i32::from(id)).write(data_write)?; } NetworkPalette::Indirect(palette) => { VarInt(palette.len() as i32).write(data_write)?; for id in palette { - VarInt(id as i32).write(data_write)?; + VarInt(i32::from(id)).write(data_write)?; } } NetworkPalette::Direct => (), diff --git a/pumpkin-protocol/src/bedrock/client/network_chunk_publisher_update.rs b/pumpkin-protocol/src/bedrock/client/network_chunk_publisher_update.rs index 36a0ac11b..629e60fa6 100644 --- a/pumpkin-protocol/src/bedrock/client/network_chunk_publisher_update.rs +++ b/pumpkin-protocol/src/bedrock/client/network_chunk_publisher_update.rs @@ -19,6 +19,7 @@ pub struct CNetworkChunkPublisherUpdate { } impl CNetworkChunkPublisherUpdate { + #[must_use] pub fn new(pos_for_view: BlockPos, new_radius: u32) -> Self { Self { pos_for_view: NetworkPos(pos_for_view), diff --git a/pumpkin-protocol/src/bedrock/client/network_settings.rs b/pumpkin-protocol/src/bedrock/client/network_settings.rs index 12c78c08c..215d6d94a 100644 --- a/pumpkin-protocol/src/bedrock/client/network_settings.rs +++ b/pumpkin-protocol/src/bedrock/client/network_settings.rs @@ -13,6 +13,7 @@ pub struct CNetworkSettings { } impl CNetworkSettings { + #[must_use] pub fn new( compression_threshold: u16, compression_method: u16, diff --git a/pumpkin-protocol/src/bedrock/client/raknet/connection.rs b/pumpkin-protocol/src/bedrock/client/raknet/connection.rs index c448e1d2d..17b0b9330 100644 --- a/pumpkin-protocol/src/bedrock/client/raknet/connection.rs +++ b/pumpkin-protocol/src/bedrock/client/raknet/connection.rs @@ -6,16 +6,15 @@ use crate::serial::PacketWrite; #[derive(PacketWrite)] #[packet(0x03)] pub struct CConnectedPong { - ping_time: u64, - pong_time: u64, + ping: u64, + pong: u64, } impl CConnectedPong { - pub fn new(ping_time: u64, pong_time: u64) -> Self { - Self { - ping_time, - pong_time, - } + #[must_use] + #[expect(clippy::similar_names)] + pub fn new(ping: u64, pong: u64) -> Self { + Self { ping, pong } } } @@ -30,6 +29,7 @@ pub struct CConnectionRequestAccepted { } impl CConnectionRequestAccepted { + #[must_use] pub fn new( client_address: SocketAddr, system_index: u16, diff --git a/pumpkin-protocol/src/bedrock/client/raknet/open_connection.rs b/pumpkin-protocol/src/bedrock/client/raknet/open_connection.rs index 4ae261121..e8ad7c26e 100644 --- a/pumpkin-protocol/src/bedrock/client/raknet/open_connection.rs +++ b/pumpkin-protocol/src/bedrock/client/raknet/open_connection.rs @@ -16,6 +16,7 @@ pub struct COpenConnectionReply1 { } impl COpenConnectionReply1 { + #[must_use] pub fn new(server_guid: u64, has_server_security: bool, mtu: u16) -> Self { Self { magic: RAKNET_MAGIC, @@ -38,6 +39,7 @@ pub struct COpenConnectionReply2 { } impl COpenConnectionReply2 { + #[must_use] pub fn new(server_guid: u64, client_address: SocketAddr, mtu: u16, security: bool) -> Self { Self { magic: RAKNET_MAGIC, diff --git a/pumpkin-protocol/src/bedrock/client/raknet/unconnected_pong.rs b/pumpkin-protocol/src/bedrock/client/raknet/unconnected_pong.rs index 5389c818d..86278aa99 100644 --- a/pumpkin-protocol/src/bedrock/client/raknet/unconnected_pong.rs +++ b/pumpkin-protocol/src/bedrock/client/raknet/unconnected_pong.rs @@ -61,6 +61,7 @@ impl fmt::Display for ServerInfo { } impl CUnconnectedPong { + #[must_use] pub fn new(time: u64, server_guid: u64, magic: [u8; 16], server_id: String) -> Self { Self { time, diff --git a/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs b/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs index 321c5e2c7..c926fc731 100644 --- a/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs +++ b/pumpkin-protocol/src/bedrock/client/resource_pack_stack.rs @@ -17,6 +17,7 @@ pub struct CResourcePackStackPacket { } impl CResourcePackStackPacket { + #[must_use] pub fn new( resource_pack_required: bool, texture_pack_list_size: VarUInt, diff --git a/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs b/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs index b26031931..2b635ed19 100644 --- a/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs +++ b/pumpkin-protocol/src/bedrock/client/resource_packs_info.rs @@ -15,6 +15,8 @@ pub struct CResourcePacksInfo { } impl CResourcePacksInfo { + #[must_use] + #[expect(clippy::fn_params_excessive_bools)] pub fn new( resource_pack_required: bool, has_addon_packs: bool, diff --git a/pumpkin-protocol/src/bedrock/client/set_actor_data.rs b/pumpkin-protocol/src/bedrock/client/set_actor_data.rs index f4ef75570..36752b27d 100644 --- a/pumpkin-protocol/src/bedrock/client/set_actor_data.rs +++ b/pumpkin-protocol/src/bedrock/client/set_actor_data.rs @@ -71,6 +71,7 @@ pub enum MetadataValue { } impl MetadataValue { + #[must_use] pub fn type_id(&self) -> u32 { match self { Self::Byte(_) => 0, diff --git a/pumpkin-protocol/src/bedrock/client/set_time.rs b/pumpkin-protocol/src/bedrock/client/set_time.rs index 5c9e16645..a618872ab 100644 --- a/pumpkin-protocol/src/bedrock/client/set_time.rs +++ b/pumpkin-protocol/src/bedrock/client/set_time.rs @@ -9,6 +9,7 @@ pub struct CSetTime { } impl CSetTime { + #[must_use] pub const fn new(time: i32) -> Self { Self { time: VarInt(time) } } diff --git a/pumpkin-protocol/src/bedrock/frame_set.rs b/pumpkin-protocol/src/bedrock/frame_set.rs index e64ee0170..a41a58ca2 100644 --- a/pumpkin-protocol/src/bedrock/frame_set.rs +++ b/pumpkin-protocol/src/bedrock/frame_set.rs @@ -51,6 +51,7 @@ pub struct Frame { } impl Frame { + #[must_use] pub fn new_unreliable(payload: Vec) -> Self { Self { reliability: RakReliability::Unreliable, @@ -71,19 +72,18 @@ impl Frame { while let Ok(header) = u8::read(reader) { let mut frame = Self::default(); let reliability_id = (header & 0xE0) >> 5; - let reliability = match RakReliability::from_id(reliability_id) { - Some(reliability) => reliability, - None => return Err(Error::other("Invalid reliability")), + let Some(reliability) = RakReliability::from_id(reliability_id) else { + return Err(Error::other("Invalid reliability")); }; let split = (header & RAKNET_SPLIT) != 0; let length = u16::read_be(reader)? >> 3; if reliability.is_reliable() { - frame.reliable_number = u24::read(reader)?.0 + frame.reliable_number = u24::read(reader)?.0; } if reliability.is_sequenced() { - frame.sequence_index = u24::read(reader)?.0 + frame.sequence_index = u24::read(reader)?.0; } if reliability.is_ordered() { diff --git a/pumpkin-protocol/src/bedrock/mod.rs b/pumpkin-protocol/src/bedrock/mod.rs index bc0ac30dc..cd45ec545 100644 --- a/pumpkin-protocol/src/bedrock/mod.rs +++ b/pumpkin-protocol/src/bedrock/mod.rs @@ -35,65 +35,68 @@ pub enum RakReliability { } impl RakReliability { + #[must_use] pub fn is_reliable(&self) -> bool { matches!( self, - RakReliability::Reliable - | RakReliability::ReliableOrdered - | RakReliability::ReliableSequenced - | RakReliability::ReliableWithAckReceipt - | RakReliability::ReliableOrderedWithAckReceipt + Self::Reliable + | Self::ReliableOrdered + | Self::ReliableSequenced + | Self::ReliableWithAckReceipt + | Self::ReliableOrderedWithAckReceipt ) } + #[must_use] pub fn is_sequenced(&self) -> bool { - matches!( - self, - RakReliability::ReliableSequenced | RakReliability::UnreliableSequenced - ) + matches!(self, Self::ReliableSequenced | Self::UnreliableSequenced) } + #[must_use] pub fn is_ordered(&self) -> bool { matches!( self, - RakReliability::UnreliableSequenced - | RakReliability::ReliableOrdered - | RakReliability::ReliableSequenced - | RakReliability::ReliableOrderedWithAckReceipt + Self::UnreliableSequenced + | Self::ReliableOrdered + | Self::ReliableSequenced + | Self::ReliableOrderedWithAckReceipt ) } + #[must_use] pub fn is_order_exclusive(&self) -> bool { matches!( self, - RakReliability::ReliableOrdered | RakReliability::ReliableOrderedWithAckReceipt + Self::ReliableOrdered | Self::ReliableOrderedWithAckReceipt ) } + #[must_use] pub fn from_id(id: u8) -> Option { match id { - 0 => Some(RakReliability::Unreliable), - 1 => Some(RakReliability::UnreliableSequenced), - 2 => Some(RakReliability::Reliable), - 3 => Some(RakReliability::ReliableOrdered), - 4 => Some(RakReliability::ReliableSequenced), - 5 => Some(RakReliability::UnreliableWithAckReceipt), - 6 => Some(RakReliability::ReliableWithAckReceipt), - 7 => Some(RakReliability::ReliableOrderedWithAckReceipt), + 0 => Some(Self::Unreliable), + 1 => Some(Self::UnreliableSequenced), + 2 => Some(Self::Reliable), + 3 => Some(Self::ReliableOrdered), + 4 => Some(Self::ReliableSequenced), + 5 => Some(Self::UnreliableWithAckReceipt), + 6 => Some(Self::ReliableWithAckReceipt), + 7 => Some(Self::ReliableOrderedWithAckReceipt), _ => None, } } + #[must_use] pub fn to_id(&self) -> u8 { match self { - RakReliability::Unreliable => 0, - RakReliability::UnreliableSequenced => 1, - RakReliability::Reliable => 2, - RakReliability::ReliableOrdered => 3, - RakReliability::ReliableSequenced => 4, - RakReliability::UnreliableWithAckReceipt => 5, - RakReliability::ReliableWithAckReceipt => 6, - RakReliability::ReliableOrderedWithAckReceipt => 7, + Self::Unreliable => 0, + Self::UnreliableSequenced => 1, + Self::Reliable => 2, + Self::ReliableOrdered => 3, + Self::ReliableSequenced => 4, + Self::UnreliableWithAckReceipt => 5, + Self::ReliableWithAckReceipt => 6, + Self::ReliableOrderedWithAckReceipt => 7, } } } diff --git a/pumpkin-protocol/src/bedrock/packet_decoder.rs b/pumpkin-protocol/src/bedrock/packet_decoder.rs index 6b2980c04..cacaeeadc 100644 --- a/pumpkin-protocol/src/bedrock/packet_decoder.rs +++ b/pumpkin-protocol/src/bedrock/packet_decoder.rs @@ -46,10 +46,11 @@ pub enum DecryptionReader { } impl DecryptionReader { + #[must_use] pub fn upgrade(self, cipher: Aes128Cfb8Dec) -> Self { match self { Self::None(stream) => Self::Decrypt(Box::new(StreamDecryptor::new(cipher, stream))), - _ => panic!("Cannot upgrade a stream that already has a cipher!"), + Self::Decrypt(_) => panic!("Cannot upgrade a stream that already has a cipher!"), } } } @@ -75,7 +76,7 @@ impl AsyncRead for DecryptionReader { } /// Decoder: Client -> Server -/// Supports ZLib decoding/decompression +/// Supports `ZLib` decoding/decompression /// Supports Aes128 Encryption pub struct UDPNetworkDecoder { compression: Option, @@ -88,6 +89,7 @@ impl Default for UDPNetworkDecoder { } impl UDPNetworkDecoder { + #[must_use] pub fn new() -> Self { Self { compression: None } } @@ -105,6 +107,7 @@ impl UDPNetworkDecoder { // take_mut::take(&mut self.reader, |decoder| decoder.upgrade(cipher)); } + #[expect(clippy::unused_async)] pub async fn get_packet_payload( &mut self, reader: Cursor>, @@ -118,7 +121,7 @@ impl UDPNetworkDecoder { Ok(reader.into_inner().into()) } - pub async fn get_game_packet( + pub fn get_game_packet( &mut self, mut reader: Cursor>, ) -> Result { @@ -134,7 +137,7 @@ impl UDPNetworkDecoder { err => PacketDecodeError::MalformedLength(err.to_string()), })?; - let packet_len = packet_len.0 as u64; + let packet_len = u64::from(packet_len.0); let var_header = VarUInt::decode(&mut reader)?; @@ -148,10 +151,10 @@ impl UDPNetworkDecoder { // SubClient Target ID (2 bits) // SubClient Target ID: Lowest 2 bits - let _sub_client_target = (header >> 10 & 0b11) as u8; + // let _sub_client_target = (header >> 10 & 0b11) as u8; // SubClient Sender ID: Next 2 bits (bits 2 and 3) - let _sub_client_sender = (header >> 12 & 0b11) as u8; + // let _sub_client_sender = (header >> 12 & 0b11) as u8; // Gamepacket ID: Remaining 10 bits (bits 4 to 13) let gamepacket_id = (header & 0x3FF) as u16; // 0x3FF is 10 bits set to 1 @@ -161,7 +164,7 @@ impl UDPNetworkDecoder { .map_err(|err| PacketDecodeError::FailedDecompression(err.to_string()))?; Ok(RawPacket { - id: gamepacket_id as i32, + id: i32::from(gamepacket_id), payload: payload.into(), }) } diff --git a/pumpkin-protocol/src/bedrock/packet_encoder.rs b/pumpkin-protocol/src/bedrock/packet_encoder.rs index d37c311e9..6dad989d0 100644 --- a/pumpkin-protocol/src/bedrock/packet_encoder.rs +++ b/pumpkin-protocol/src/bedrock/packet_encoder.rs @@ -5,7 +5,6 @@ use std::{ task::{Context, Poll}, }; -use bytes::Bytes; use thiserror::Error; use tokio::{io::AsyncWrite, net::UdpSocket}; @@ -22,10 +21,11 @@ pub enum EncryptionWriter { } impl EncryptionWriter { + #[must_use] pub fn upgrade(self, cipher: Aes128Cfb8Enc) -> Self { match self { Self::None(stream) => Self::Encrypt(Box::new(StreamEncryptor::new(cipher, stream))), - _ => panic!("Cannot upgrade a stream that already has a cipher!"), + Self::Encrypt(_) => panic!("Cannot upgrade a stream that already has a cipher!"), } } } @@ -76,7 +76,7 @@ impl AsyncWrite for EncryptionWriter { } /// Encoder: Server -> Client -/// Supports ZLib endecoding/compression +/// Supports `ZLib` endecoding/compression /// Supports Aes128 Encryption pub struct UDPNetworkEncoder { // compression and compression threshold @@ -90,6 +90,7 @@ impl Default for UDPNetworkEncoder { } impl UDPNetworkEncoder { + #[must_use] pub fn new() -> Self { Self { compression: None } } @@ -107,12 +108,12 @@ impl UDPNetworkEncoder { // take_mut::take(&mut self.writer, |encoder| encoder.upgrade(cipher)); } - pub async fn write_game_packet( + pub fn write_game_packet( &mut self, packet_id: u16, sub_client_sender: SubClient, sub_client_target: SubClient, - packet_payload: Bytes, + packet_payload: &[u8], mut writer: impl Write, ) -> Result<(), Error> { // Game Packet ID @@ -128,7 +129,7 @@ impl UDPNetworkEncoder { // Gamepacket ID (10 bits) << 4 (offset by 2 bits for target + 2 bits for sender) // SubClient Sender ID (2 bits) << 2 (offset by 2 bits for target) // SubClient Target ID (2 bits) - let header_value: u32 = packet_id as u32 + let header_value: u32 = u32::from(packet_id) | ((sub_client_sender as u32) << 10) | ((sub_client_target as u32) << 12); @@ -158,7 +159,7 @@ impl UDPNetworkEncoder { .unwrap(); // 5. Write the payload - writer.write_all(&packet_payload) + writer.write_all(packet_payload) } pub async fn write_packet( diff --git a/pumpkin-protocol/src/bedrock/server/loading_screen.rs b/pumpkin-protocol/src/bedrock/server/loading_screen.rs index db2b810ea..aaafebea5 100644 --- a/pumpkin-protocol/src/bedrock/server/loading_screen.rs +++ b/pumpkin-protocol/src/bedrock/server/loading_screen.rs @@ -13,6 +13,7 @@ pub struct SLoadingScreen { } impl SLoadingScreen { + #[must_use] pub fn is_loading_done(&self) -> bool { self.status.0 == 2 } diff --git a/pumpkin-protocol/src/bedrock/server/text.rs b/pumpkin-protocol/src/bedrock/server/text.rs index 1fa35efca..c70ae46ed 100644 --- a/pumpkin-protocol/src/bedrock/server/text.rs +++ b/pumpkin-protocol/src/bedrock/server/text.rs @@ -19,6 +19,7 @@ pub struct SText { } impl SText { + #[must_use] pub fn new(message: String, source_name: String) -> Self { Self { needs_translation: false, @@ -36,6 +37,7 @@ impl SText { } } + #[must_use] pub fn system_message(message: String) -> Self { Self { needs_translation: false, @@ -97,10 +99,7 @@ impl PacketRead for SText { if actual != expected { return Err(Error::new( ErrorKind::InvalidData, - format!( - "Dummy string mismatch: expected {}, got {}", - expected, actual - ), + format!("Dummy string mismatch: expected {expected}, got {actual}"), )); } } diff --git a/pumpkin-protocol/src/codec/bedrock_block_pos.rs b/pumpkin-protocol/src/codec/bedrock_block_pos.rs index 00243aa98..b28a7b9d3 100644 --- a/pumpkin-protocol/src/codec/bedrock_block_pos.rs +++ b/pumpkin-protocol/src/codec/bedrock_block_pos.rs @@ -10,7 +10,7 @@ use crate::{ /// A wrapper for `BlockPos` that handles Bedrock-specific network serialization. /// /// Bedrock Edition encodes coordinates differently than Java Edition, using -/// VarInt's to save bandwidth. +/// `VarInt`'s to save bandwidth. pub struct NetworkPos(pub BlockPos); impl NetworkPos { diff --git a/pumpkin-protocol/src/codec/bit_set.rs b/pumpkin-protocol/src/codec/bit_set.rs index fddc33d2d..0bfa303f5 100644 --- a/pumpkin-protocol/src/codec/bit_set.rs +++ b/pumpkin-protocol/src/codec/bit_set.rs @@ -31,7 +31,7 @@ impl BitSet { let long = read.get_i64_be()?; array.push(long); } - Ok(BitSet(array.into_boxed_slice())) + Ok(Self(array.into_boxed_slice())) } } diff --git a/pumpkin-protocol/src/codec/bitset.rs b/pumpkin-protocol/src/codec/bitset.rs index 71dba33bd..f478265dc 100644 --- a/pumpkin-protocol/src/codec/bitset.rs +++ b/pumpkin-protocol/src/codec/bitset.rs @@ -10,17 +10,13 @@ pub struct Bitset { impl Bitset { pub fn get>(&self, index: T) -> bool { let index: usize = index.into(); - if index > N { - panic!("") - } + assert!(index <= N, ""); (self.bits & (1 << index)) != 0 } pub fn set>(&mut self, index: T, value: bool) { let index: usize = index.into(); - if index > N { - panic!("") - } + assert!(index <= N, ""); if value { self.bits |= 1 << index; } else { @@ -31,16 +27,14 @@ impl Bitset { impl Default for Bitset { fn default() -> Self { - if N > 80 { - panic!() - } + assert!(N <= 80,); Self { bits: 0 } } } impl PacketRead for Bitset { fn read(reader: &mut R) -> Result { - let mut bitset = Bitset::::default(); + let mut bitset = Self::default(); for i in 0..N.div_ceil(8) { let byte = u8::read(reader)?; diff --git a/pumpkin-protocol/src/codec/data_component.rs b/pumpkin-protocol/src/codec/data_component.rs index 00b6183df..ccf19738e 100644 --- a/pumpkin-protocol/src/codec/data_component.rs +++ b/pumpkin-protocol/src/codec/data_component.rs @@ -71,7 +71,7 @@ impl DataComponentCodec for EnchantmentsImpl { "EnchantmentsImpl Enchantment VarInt Incorrect!", ))?, level, - )) + )); } Ok(Self { enchantment: Cow::from(enc), diff --git a/pumpkin-protocol/src/codec/item_stack_seralizer.rs b/pumpkin-protocol/src/codec/item_stack_seralizer.rs index eaceed23c..177e6d5a1 100644 --- a/pumpkin-protocol/src/codec/item_stack_seralizer.rs +++ b/pumpkin-protocol/src/codec/item_stack_seralizer.rs @@ -57,7 +57,7 @@ impl<'de> Deserialize<'de> for ItemStackSerializer<'static> { let _byte_len = seq .next_element::()? .ok_or(de::Error::custom("No data len VarInt!"))?; - patch.push((id, Some(deserialize(id, &mut seq)?))) + patch.push((id, Some(deserialize(id, &mut seq)?))); } for _ in 0..num_components_to_remove { let id = seq @@ -68,7 +68,7 @@ impl<'de> Deserialize<'de> for ItemStackSerializer<'static> { .map_err(|_| de::Error::custom("Unknown component id VarInt!"))?; let id = DataComponent::try_from_id(id) .ok_or(de::Error::custom("Unknown component id VarInt!"))?; - patch.push((id, None)) + patch.push((id, None)); } let item_id: u16 = item_id @@ -131,6 +131,7 @@ impl Serialize for ItemStackSerializer<'_> { } impl ItemStackSerializer<'_> { + #[must_use] pub fn to_stack(self) -> ItemStack { self.0.into_owned() } @@ -144,10 +145,10 @@ impl From for ItemStackSerializer<'_> { impl From> for ItemStackSerializer<'_> { fn from(item: Option) -> Self { - match item { - Some(item) => ItemStackSerializer::from(item), - None => ItemStackSerializer(Cow::Borrowed(ItemStack::EMPTY)), - } + item.map_or_else( + || ItemStackSerializer(Cow::Borrowed(ItemStack::EMPTY)), + ItemStackSerializer::from, + ) } } @@ -165,6 +166,7 @@ pub struct ItemStackHash { } impl OptionalItemStackHash { + #[must_use] pub fn hash_equals(&self, other: &ItemStack) -> bool { if let Some(hash) = &self.0 { if hash.item_id != other.item.id.into() || hash.count != other.item_count.into() { @@ -193,11 +195,10 @@ impl OptionalItemStackHash { let checksum = data.get_hash(); for (id, hash) in &hash.components.added { if id == &VarInt::from(other_id.to_id()) { - if hash != &checksum { - return false; - } else { + if hash == &checksum { break; } + return false; } } } else if !hash diff --git a/pumpkin-protocol/src/codec/optional_int.rs b/pumpkin-protocol/src/codec/optional_int.rs index 5a599594d..8bef68636 100644 --- a/pumpkin-protocol/src/codec/optional_int.rs +++ b/pumpkin-protocol/src/codec/optional_int.rs @@ -8,10 +8,7 @@ pub struct OptionalInt(pub Option); impl Serialize for OptionalInt { fn serialize(&self, serializer: S) -> Result { // Vanilla logic: empty is 0, otherwise value + 1 - let val = match self.0 { - None => 0, - Some(id) => id + 1, - }; + let val = self.0.map_or(0, |id| id + 1); VarInt(val).serialize(serializer) } } diff --git a/pumpkin-protocol/src/codec/u24_type.rs b/pumpkin-protocol/src/codec/u24_type.rs index 379daced6..b3912916d 100644 --- a/pumpkin-protocol/src/codec/u24_type.rs +++ b/pumpkin-protocol/src/codec/u24_type.rs @@ -17,6 +17,6 @@ impl PacketRead for u24 { fn read(reader: &mut R) -> Result { let mut buf = [0; 3]; reader.read_exact(&mut buf)?; - Ok(u24(u32::from_le_bytes([buf[0], buf[1], buf[2], 0]))) + Ok(Self(u32::from_le_bytes([buf[0], buf[1], buf[2], 0]))) } } diff --git a/pumpkin-protocol/src/codec/var_int.rs b/pumpkin-protocol/src/codec/var_int.rs index daa83c4f8..77376b292 100644 --- a/pumpkin-protocol/src/codec/var_int.rs +++ b/pumpkin-protocol/src/codec/var_int.rs @@ -28,8 +28,9 @@ impl VarInt { /// The maximum number of bytes a `VarInt` can occupy. const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(5).unwrap(); - /// Returns the exact number of bytes this VarInt will write when + /// Returns the exact number of bytes this `VarInt` will write when /// [`Encode::encode`] is called, assuming no error occurs. + #[must_use] pub fn written_size(&self) -> usize { match self.0 { 0 => 1, @@ -57,7 +58,7 @@ impl VarInt { let byte = read.get_u8()?; val |= (i32::from(byte) & 0x7F) << (i * 7); if byte & 0x80 == 0 { - return Ok(VarInt(val)); + return Ok(Self(val)); } } Err(ReadingError::TooLarge("VarInt".to_string())) @@ -77,7 +78,7 @@ impl VarInt { })?; val |= (i32::from(byte) & 0x7F) << (i * 7); if byte & 0x80 == 0 { - return Ok(VarInt(val)); + return Ok(Self(val)); } } Err(ReadingError::TooLarge("VarInt".to_string())) @@ -89,10 +90,10 @@ impl VarInt { ) -> Result<(), WritingError> { let mut val = self.0; for _ in 0..Self::MAX_SIZE.get() { - let b: u8 = val as u8 & 0b01111111; + let b: u8 = val as u8 & 0b0111_1111; val >>= 7; write - .write_u8(if val == 0 { b } else { b | 0b10000000 }) + .write_u8(if val == 0 { b } else { b | 0b1000_0000 }) .await .map_err(WritingError::IoError)?; if val == 0 { @@ -183,8 +184,8 @@ impl<'de> Deserialize<'de> for VarInt { let mut val = 0; for i in 0..VarInt::MAX_SIZE.get() { if let Some(byte) = seq.next_element::()? { - val |= (i32::from(byte) & 0b01111111) << (i * 7); - if byte & 0b10000000 == 0 { + val |= (i32::from(byte) & 0b0111_1111) << (i * 7); + if byte & 0b1000_0000 == 0 { return Ok(VarInt(val)); } } else { @@ -220,7 +221,7 @@ impl PacketRead for VarInt { let byte = u8::read(read)?; val |= (i32::from(byte) & 0x7F) << (i * 7); if byte & 0x80 == 0 { - return Ok(VarInt((val >> 1) ^ (val << 31))); + return Ok(Self((val >> 1) ^ (val << 31))); } } Err(Error::new(ErrorKind::InvalidData, "")) diff --git a/pumpkin-protocol/src/codec/var_long.rs b/pumpkin-protocol/src/codec/var_long.rs index b85ef94b1..813c62ad5 100644 --- a/pumpkin-protocol/src/codec/var_long.rs +++ b/pumpkin-protocol/src/codec/var_long.rs @@ -46,7 +46,7 @@ impl VarLong { let byte = read.get_u8()?; val |= (i64::from(byte) & 0x7F) << (i * 7); if byte & 0x80 == 0 { - return Ok(VarLong(val)); + return Ok(Self(val)); } } Err(ReadingError::TooLarge("VarLong".to_string())) @@ -55,25 +55,25 @@ impl VarLong { impl From for VarLong { fn from(value: i64) -> Self { - VarLong(value) + Self(value) } } impl From for VarLong { fn from(value: u32) -> Self { - VarLong(value as i64) + Self(i64::from(value)) } } impl From for VarLong { fn from(value: u8) -> Self { - VarLong(value as i64) + Self(i64::from(value)) } } impl From for VarLong { fn from(value: usize) -> Self { - VarLong(value as i64) + Self(value as i64) } } @@ -128,8 +128,8 @@ impl<'de> Deserialize<'de> for VarLong { let mut val = 0; for i in 0..VarLong::MAX_SIZE.get() { if let Some(byte) = seq.next_element::()? { - val |= (i64::from(byte) & 0b01111111) << (i * 7); - if byte & 0b10000000 == 0 { + val |= (i64::from(byte) & 0b0111_1111) << (i * 7); + if byte & 0b1000_0000 == 0 { return Ok(VarLong(val)); } } else { diff --git a/pumpkin-protocol/src/codec/var_uint.rs b/pumpkin-protocol/src/codec/var_uint.rs index a1edd1821..c99c844be 100644 --- a/pumpkin-protocol/src/codec/var_uint.rs +++ b/pumpkin-protocol/src/codec/var_uint.rs @@ -27,8 +27,9 @@ impl VarUInt { /// The maximum number of bytes a `VarUInt` can occupy. const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(5).unwrap(); - /// Returns the exact number of bytes this VarUInt will write when + /// Returns the exact number of bytes this `VarUInt` will write when /// [`Encode::encode`] is called, assuming no error occurs. + #[must_use] pub fn written_size(&self) -> usize { (32 - self.0.leading_zeros() as usize).max(1).div_ceil(7) } @@ -56,7 +57,7 @@ impl VarUInt { let byte = read.get_u8()?; val |= (u32::from(byte) & 0x7F) << (i * 7); if byte & 0x80 == 0 { - return Ok(VarUInt(val)); + return Ok(Self(val)); } } Err(ReadingError::TooLarge("VarUInt".to_string())) @@ -76,7 +77,7 @@ impl VarUInt { })?; val |= (u32::from(byte) & 0x7F) << (i * 7); if byte & 0x80 == 0 { - return Ok(VarUInt(val)); + return Ok(Self(val)); } } Err(ReadingError::TooLarge("VarUInt".to_string())) @@ -88,10 +89,10 @@ impl VarUInt { ) -> Result<(), WritingError> { let mut val = self.0; for _ in 0..Self::MAX_SIZE.get() { - let b: u8 = val as u8 & 0b01111111; + let b: u8 = val as u8 & 0b0111_1111; val >>= 7; write - .write_u8(if val == 0 { b } else { b | 0b10000000 }) + .write_u8(if val == 0 { b } else { b | 0b1000_0000 }) .await .map_err(WritingError::IoError)?; if val == 0 { @@ -166,8 +167,8 @@ impl<'de> Deserialize<'de> for VarUInt { let mut val = 0; for i in 0..VarUInt::MAX_SIZE.get() { if let Some(byte) = seq.next_element::()? { - val |= (u32::from(byte) & 0b01111111) << (i * 7); - if byte & 0b10000000 == 0 { + val |= (u32::from(byte) & 0b0111_1111) << (i * 7); + if byte & 0b1000_0000 == 0 { return Ok(VarUInt(val)); } } else { @@ -207,7 +208,7 @@ impl PacketRead for VarUInt { let byte = u8::read(reader)?; val |= (u32::from(byte) & 0x7F) << (i * 7); if byte & 0x80 == 0 { - return Ok(VarUInt(val)); + return Ok(Self(val)); } } Err(Error::new(ErrorKind::InvalidData, "")) diff --git a/pumpkin-protocol/src/codec/var_ulong.rs b/pumpkin-protocol/src/codec/var_ulong.rs index db04df9f0..caeea916a 100644 --- a/pumpkin-protocol/src/codec/var_ulong.rs +++ b/pumpkin-protocol/src/codec/var_ulong.rs @@ -27,8 +27,9 @@ impl VarULong { /// The maximum number of bytes a `VarULong` can occupy. const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(10).unwrap(); - /// Returns the exact number of bytes this VarLong will write when + /// Returns the exact number of bytes this `VarLong` will write when /// [`Encode::encode`] is called, assuming no error occurs. + #[must_use] pub fn written_size(&self) -> usize { match self.0 { 0 => 1, @@ -56,9 +57,9 @@ impl VarULong { let mut val = 0; for i in 0..Self::MAX_SIZE.get() { let byte = read.get_u8()?; - val |= (u64::from(byte) & 0b01111111) << (i * 7); - if byte & 0b10000000 == 0 { - return Ok(VarULong(val)); + val |= (u64::from(byte) & 0b0111_1111) << (i * 7); + if byte & 0b1000_0000 == 0 { + return Ok(Self(val)); } } Err(ReadingError::TooLarge("VarLong".to_string())) @@ -67,25 +68,25 @@ impl VarULong { impl From for VarULong { fn from(value: u64) -> Self { - VarULong(value) + Self(value) } } impl From for VarULong { fn from(value: u32) -> Self { - VarULong(value as u64) + Self(u64::from(value)) } } impl From for VarULong { fn from(value: u8) -> Self { - VarULong(value as u64) + Self(u64::from(value)) } } impl From for VarULong { fn from(value: usize) -> Self { - VarULong(value as u64) + Self(value as u64) } } @@ -140,8 +141,8 @@ impl<'de> Deserialize<'de> for VarULong { let mut val = 0; for i in 0..VarULong::MAX_SIZE.get() { if let Some(byte) = seq.next_element::()? { - val |= (u64::from(byte) & 0b01111111) << (i * 7); - if byte & 0b10000000 == 0 { + val |= (u64::from(byte) & 0b0111_1111) << (i * 7); + if byte & 0b1000_0000 == 0 { return Ok(VarULong(val)); } } else { @@ -178,9 +179,9 @@ impl PacketRead for VarULong { let mut val = 0; for i in 0..Self::MAX_SIZE.get() { let byte = u8::read(reader)?; - val |= (u64::from(byte) & 0b01111111) << (i * 7); - if byte & 0b10000000 == 0 { - return Ok(VarULong(val)); + val |= (u64::from(byte) & 0b0111_1111) << (i * 7); + if byte & 0b1000_0000 == 0 { + return Ok(Self(val)); } } Err(Error::other("Invalid VarUInt")) diff --git a/pumpkin-protocol/src/codec/velocity.rs b/pumpkin-protocol/src/codec/velocity.rs index 8f0b209ae..3aa2e85ee 100644 --- a/pumpkin-protocol/src/codec/velocity.rs +++ b/pumpkin-protocol/src/codec/velocity.rs @@ -12,38 +12,47 @@ pub struct Velocity(pub Vector3); impl Velocity { pub fn write(&self, writer: &mut W) -> Result<(), WritingError> { let velocity = self.0; - let d = clamp_value(velocity.x); - let e = clamp_value(velocity.y); - let f = clamp_value(velocity.z); - let g = abs_max(d, abs_max(e, f)); - if g < MIN_VELOCITY_MAGNITUDE { + // Clamp and find the maximum component magnitude + let clamped_x = clamp_value(velocity.x); + let clamped_y = clamp_value(velocity.y); + let clamped_z = clamp_value(velocity.z); + let max_component = abs_max(clamped_x, abs_max(clamped_y, clamped_z)); + + if max_component < MIN_VELOCITY_MAGNITUDE { return writer.write_slice(&[0u8]); } - let l = g.ceil() as i64; - let bl = l > 3; + let scale_factor = max_component.ceil() as i64; + let is_extended = scale_factor > 3; // The header byte: bits 0-1 are scale, bit 2 is the extension flag - let m = if bl { (l & 3) | 4 } else { l }; + let header = if is_extended { + (scale_factor & 3) | 4 + } else { + scale_factor + }; - // Pack the 15-bit quantized components into a 64-bit long - // n (x): bits 3-17 | o (y): bits 18-32 | p (z): bits 33-47 - let n = to_long(d / l as f64) << 3; - let o = to_long(e / l as f64) << 18; - let p = to_long(f / l as f64) << 33; + // Pack the 15-bit quantized components into a 64-bit buffer + // Quantized components: x (bits 3-17), y (bits 18-32), z (bits 33-47) + let quantized_x = to_long(clamped_x / scale_factor as f64) << 3; + let quantized_y = to_long(clamped_y / scale_factor as f64) << 18; + let quantized_z = to_long(clamped_z / scale_factor as f64) << 33; - let packed_data: i64 = m | n | o | p; + let packed_data: i64 = header | quantized_x | quantized_y | quantized_z; + // Write low 16 bits (Little Endian) writer .write_all(&(packed_data as u16).to_le_bytes()) - .unwrap(); // Write low 16 bits + .unwrap(); + + // Write next 32 bits (Big Endian) writer .write_all(&((packed_data >> 16) as i32).to_be_bytes()) - .unwrap(); // Write next 32 bits + .unwrap(); - if bl { - let scale_tail = VarInt((l >> 2) as i32); + if is_extended { + let scale_tail = VarInt((scale_factor >> 2) as i32); writer.write_var_int(&scale_tail)?; } @@ -51,8 +60,8 @@ impl Velocity { } } -const MAX_VELOCITY_CLAMP: f64 = 1.7179869183E10; -const MIN_VELOCITY_MAGNITUDE: f64 = 3.051944088384301E-5; +const MAX_VELOCITY_CLAMP: f64 = 1.717_986_918_3E10; +const MIN_VELOCITY_MAGNITUDE: f64 = 3.051_944_088_384_301E-5; const MAX_15_BIT_VALUE: f64 = 32766.0; fn clamp_value(value: f64) -> f64 { diff --git a/pumpkin-protocol/src/java/client/config/add_resource_pack.rs b/pumpkin-protocol/src/java/client/config/add_resource_pack.rs index e13e2b86a..5c727474d 100644 --- a/pumpkin-protocol/src/java/client/config/add_resource_pack.rs +++ b/pumpkin-protocol/src/java/client/config/add_resource_pack.rs @@ -17,6 +17,7 @@ pub struct CConfigAddResourcePack<'a> { } impl<'a> CConfigAddResourcePack<'a> { + #[must_use] pub fn new( uuid: &'a uuid::Uuid, url: &'a str, diff --git a/pumpkin-protocol/src/java/client/config/config_disconnect.rs b/pumpkin-protocol/src/java/client/config/config_disconnect.rs index 643b39615..64920e82b 100644 --- a/pumpkin-protocol/src/java/client/config/config_disconnect.rs +++ b/pumpkin-protocol/src/java/client/config/config_disconnect.rs @@ -9,6 +9,7 @@ pub struct CConfigDisconnect<'a> { } impl<'a> CConfigDisconnect<'a> { + #[must_use] pub fn new(reason: &'a str) -> Self { Self { reason } } diff --git a/pumpkin-protocol/src/java/client/config/cookie_request.rs b/pumpkin-protocol/src/java/client/config/cookie_request.rs index 0de570598..e8bb56b10 100644 --- a/pumpkin-protocol/src/java/client/config/cookie_request.rs +++ b/pumpkin-protocol/src/java/client/config/cookie_request.rs @@ -10,6 +10,7 @@ pub struct CCookieRequest<'a> { } impl<'a> CCookieRequest<'a> { + #[must_use] pub fn new(key: &'a ResourceLocation) -> Self { Self { key } } diff --git a/pumpkin-protocol/src/java/client/config/known_packs.rs b/pumpkin-protocol/src/java/client/config/known_packs.rs index 07320295b..a5e6fd95c 100644 --- a/pumpkin-protocol/src/java/client/config/known_packs.rs +++ b/pumpkin-protocol/src/java/client/config/known_packs.rs @@ -11,6 +11,7 @@ pub struct CKnownPacks<'a> { } impl<'a> CKnownPacks<'a> { + #[must_use] pub fn new(known_packs: &'a [KnownPack]) -> Self { Self { known_packs } } diff --git a/pumpkin-protocol/src/java/client/config/plugin_message.rs b/pumpkin-protocol/src/java/client/config/plugin_message.rs index 9ef1ca7e1..fae75b8f2 100644 --- a/pumpkin-protocol/src/java/client/config/plugin_message.rs +++ b/pumpkin-protocol/src/java/client/config/plugin_message.rs @@ -13,6 +13,7 @@ pub struct CPluginMessage<'a> { } impl<'a> CPluginMessage<'a> { + #[must_use] pub fn new(channel: &'a str, data: &'a [u8]) -> Self { Self { channel, data } } diff --git a/pumpkin-protocol/src/java/client/config/registry_data.rs b/pumpkin-protocol/src/java/client/config/registry_data.rs index e8197a9f6..d7bda7ba1 100644 --- a/pumpkin-protocol/src/java/client/config/registry_data.rs +++ b/pumpkin-protocol/src/java/client/config/registry_data.rs @@ -12,6 +12,7 @@ pub struct CRegistryData<'a> { } impl<'a> CRegistryData<'a> { + #[must_use] pub fn new(registry_id: &'a ResourceLocation, entries: &'a [RegistryEntry]) -> Self { Self { registry_id, @@ -29,6 +30,7 @@ pub struct RegistryEntry { // TODO: No unwraps impl RegistryEntry { + #[must_use] pub fn new(entry_id: ResourceLocation, data: Option>) -> Self { Self { entry_id, data } } @@ -36,13 +38,14 @@ impl RegistryEntry { pub fn from_nbt(name: &str, nbt: &impl Serialize) -> Self { let mut data_buf = Vec::new(); pumpkin_nbt::serializer::to_bytes_unnamed(nbt, &mut data_buf).unwrap(); - RegistryEntry { + Self { entry_id: ResourceLocation::vanilla(name), data: Some(data_buf.into_boxed_slice()), } } + #[must_use] pub fn none(name: &str) -> Self { - RegistryEntry { + Self { entry_id: ResourceLocation::vanilla(name), data: None, } @@ -50,7 +53,7 @@ impl RegistryEntry { pub fn from_nbt_custom(name: &str, nbt: &impl Serialize) -> Self { let mut data_buf = Vec::new(); pumpkin_nbt::serializer::to_bytes_unnamed(nbt, &mut data_buf).unwrap(); - RegistryEntry { + Self { entry_id: ResourceLocation::pumpkin(name), data: Some(data_buf.into_boxed_slice()), } diff --git a/pumpkin-protocol/src/java/client/config/server_links.rs b/pumpkin-protocol/src/java/client/config/server_links.rs index 6e9dcf980..24dad3fdb 100644 --- a/pumpkin-protocol/src/java/client/config/server_links.rs +++ b/pumpkin-protocol/src/java/client/config/server_links.rs @@ -10,6 +10,7 @@ pub struct CConfigServerLinks<'a> { } impl<'a> CConfigServerLinks<'a> { + #[must_use] pub fn new(links: &'a [Link<'a>]) -> Self { Self { links } } diff --git a/pumpkin-protocol/src/java/client/config/store_cookie.rs b/pumpkin-protocol/src/java/client/config/store_cookie.rs index 0e4b6af92..74e697216 100644 --- a/pumpkin-protocol/src/java/client/config/store_cookie.rs +++ b/pumpkin-protocol/src/java/client/config/store_cookie.rs @@ -12,6 +12,7 @@ pub struct CStoreCookie<'a> { } impl<'a> CStoreCookie<'a> { + #[must_use] pub fn new(key: &'a ResourceLocation, payload: &'a [u8]) -> Self { Self { key, payload } } diff --git a/pumpkin-protocol/src/java/client/config/transfer.rs b/pumpkin-protocol/src/java/client/config/transfer.rs index 01c4dff6f..2685c54f2 100644 --- a/pumpkin-protocol/src/java/client/config/transfer.rs +++ b/pumpkin-protocol/src/java/client/config/transfer.rs @@ -11,6 +11,7 @@ pub struct CTransfer<'a> { } impl<'a> CTransfer<'a> { + #[must_use] pub fn new(host: &'a str, port: &'a VarInt) -> Self { Self { host, port } } diff --git a/pumpkin-protocol/src/java/client/config/update_tags.rs b/pumpkin-protocol/src/java/client/config/update_tags.rs index 2ecff0285..015aedfe1 100644 --- a/pumpkin-protocol/src/java/client/config/update_tags.rs +++ b/pumpkin-protocol/src/java/client/config/update_tags.rs @@ -17,6 +17,7 @@ pub struct CUpdateTags<'a> { } impl<'a> CUpdateTags<'a> { + #[must_use] pub fn new(tags: &'a [RegistryKey]) -> Self { Self { tags } } diff --git a/pumpkin-protocol/src/java/client/login/cookie_request.rs b/pumpkin-protocol/src/java/client/login/cookie_request.rs index da7fb6c98..59a16b75c 100644 --- a/pumpkin-protocol/src/java/client/login/cookie_request.rs +++ b/pumpkin-protocol/src/java/client/login/cookie_request.rs @@ -15,6 +15,7 @@ pub struct CLoginCookieRequest<'a> { } impl<'a> CLoginCookieRequest<'a> { + #[must_use] pub fn new(key: &'a ResourceLocation) -> Self { Self { key } } diff --git a/pumpkin-protocol/src/java/client/login/encryption_request.rs b/pumpkin-protocol/src/java/client/login/encryption_request.rs index 9292869c5..818269b4c 100644 --- a/pumpkin-protocol/src/java/client/login/encryption_request.rs +++ b/pumpkin-protocol/src/java/client/login/encryption_request.rs @@ -24,6 +24,7 @@ pub struct CEncryptionRequest<'a> { } impl<'a> CEncryptionRequest<'a> { + #[must_use] pub fn new( server_id: &'a str, public_key: &'a [u8], diff --git a/pumpkin-protocol/src/java/client/login/login_disconnect.rs b/pumpkin-protocol/src/java/client/login/login_disconnect.rs index d6b6e9831..f7b03a8cc 100644 --- a/pumpkin-protocol/src/java/client/login/login_disconnect.rs +++ b/pumpkin-protocol/src/java/client/login/login_disconnect.rs @@ -14,6 +14,7 @@ pub struct CLoginDisconnect { } impl CLoginDisconnect { + #[must_use] pub fn new(json_reason: String) -> Self { Self { json_reason } } diff --git a/pumpkin-protocol/src/java/client/login/login_success.rs b/pumpkin-protocol/src/java/client/login/login_success.rs index 41716e07e..c4ddcbb46 100644 --- a/pumpkin-protocol/src/java/client/login/login_success.rs +++ b/pumpkin-protocol/src/java/client/login/login_success.rs @@ -21,6 +21,7 @@ pub struct CLoginSuccess<'a> { } impl<'a> CLoginSuccess<'a> { + #[must_use] pub fn new(uuid: &'a uuid::Uuid, username: &'a str, properties: &'a [Property]) -> Self { Self { uuid, diff --git a/pumpkin-protocol/src/java/client/login/plugin_request.rs b/pumpkin-protocol/src/java/client/login/plugin_request.rs index 7c612861e..d4b8aaf89 100644 --- a/pumpkin-protocol/src/java/client/login/plugin_request.rs +++ b/pumpkin-protocol/src/java/client/login/plugin_request.rs @@ -23,6 +23,7 @@ pub struct CLoginPluginRequest<'a> { } impl<'a> CLoginPluginRequest<'a> { + #[must_use] pub fn new(message_id: VarInt, channel: &'a str, data: &'a [u8]) -> Self { Self { message_id, diff --git a/pumpkin-protocol/src/java/client/login/set_compression.rs b/pumpkin-protocol/src/java/client/login/set_compression.rs index 0b520effd..9ebc5f242 100644 --- a/pumpkin-protocol/src/java/client/login/set_compression.rs +++ b/pumpkin-protocol/src/java/client/login/set_compression.rs @@ -19,6 +19,7 @@ pub struct CSetCompression { } impl CSetCompression { + #[must_use] pub fn new(threshold: VarInt) -> Self { Self { threshold } } diff --git a/pumpkin-protocol/src/java/client/play/acknowledge_block.rs b/pumpkin-protocol/src/java/client/play/acknowledge_block.rs index 4f09cdd25..279202a1c 100644 --- a/pumpkin-protocol/src/java/client/play/acknowledge_block.rs +++ b/pumpkin-protocol/src/java/client/play/acknowledge_block.rs @@ -20,6 +20,7 @@ pub struct CAcknowledgeBlockChange { } impl CAcknowledgeBlockChange { + #[must_use] pub fn new(sequence_id: VarInt) -> Self { Self { sequence_id } } diff --git a/pumpkin-protocol/src/java/client/play/actionbar.rs b/pumpkin-protocol/src/java/client/play/actionbar.rs index 537da20d4..3a3bd9602 100644 --- a/pumpkin-protocol/src/java/client/play/actionbar.rs +++ b/pumpkin-protocol/src/java/client/play/actionbar.rs @@ -17,6 +17,7 @@ pub struct CActionBar<'a> { } impl<'a> CActionBar<'a> { + #[must_use] pub fn new(action_bar: &'a TextComponent) -> Self { Self { action_bar } } diff --git a/pumpkin-protocol/src/java/client/play/block_destroy_stage.rs b/pumpkin-protocol/src/java/client/play/block_destroy_stage.rs index e12dfaae8..ede9021fb 100644 --- a/pumpkin-protocol/src/java/client/play/block_destroy_stage.rs +++ b/pumpkin-protocol/src/java/client/play/block_destroy_stage.rs @@ -24,6 +24,7 @@ pub struct CSetBlockDestroyStage { } impl CSetBlockDestroyStage { + #[must_use] pub fn new(entity_id: VarInt, location: BlockPos, destroy_stage: i8) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/block_entity_data.rs b/pumpkin-protocol/src/java/client/play/block_entity_data.rs index 1962cd450..910e343c2 100644 --- a/pumpkin-protocol/src/java/client/play/block_entity_data.rs +++ b/pumpkin-protocol/src/java/client/play/block_entity_data.rs @@ -22,6 +22,7 @@ pub struct CBlockEntityData { } impl CBlockEntityData { + #[must_use] pub fn new(location: BlockPos, r#type: VarInt, nbt_data: Box<[u8]>) -> Self { Self { location, diff --git a/pumpkin-protocol/src/java/client/play/block_event.rs b/pumpkin-protocol/src/java/client/play/block_event.rs index f4293ae2f..a98a607e7 100644 --- a/pumpkin-protocol/src/java/client/play/block_event.rs +++ b/pumpkin-protocol/src/java/client/play/block_event.rs @@ -25,6 +25,7 @@ pub struct CBlockEvent { } impl CBlockEvent { + #[must_use] pub fn new( location: BlockPos, action_id: u8, diff --git a/pumpkin-protocol/src/java/client/play/block_update.rs b/pumpkin-protocol/src/java/client/play/block_update.rs index 827a3ef62..6877b0c67 100644 --- a/pumpkin-protocol/src/java/client/play/block_update.rs +++ b/pumpkin-protocol/src/java/client/play/block_update.rs @@ -20,6 +20,7 @@ pub struct CBlockUpdate { } impl CBlockUpdate { + #[must_use] pub fn new(location: BlockPos, state_id: VarInt) -> Self { Self { location, state_id } } diff --git a/pumpkin-protocol/src/java/client/play/boss_event.rs b/pumpkin-protocol/src/java/client/play/boss_event.rs index 7e787600d..51aa18826 100644 --- a/pumpkin-protocol/src/java/client/play/boss_event.rs +++ b/pumpkin-protocol/src/java/client/play/boss_event.rs @@ -20,6 +20,7 @@ pub struct CBossEvent<'a> { } impl<'a> CBossEvent<'a> { + #[must_use] pub fn new(uuid: &'a uuid::Uuid, action: BosseventAction) -> Self { Self { uuid, action } } diff --git a/pumpkin-protocol/src/java/client/play/change_difficulty.rs b/pumpkin-protocol/src/java/client/play/change_difficulty.rs index c6bd9c19d..d4711a859 100644 --- a/pumpkin-protocol/src/java/client/play/change_difficulty.rs +++ b/pumpkin-protocol/src/java/client/play/change_difficulty.rs @@ -23,6 +23,7 @@ pub struct CChangeDifficulty { } impl CChangeDifficulty { + #[must_use] pub fn new(difficulty: u8, locked: bool) -> Self { Self { difficulty, locked } } diff --git a/pumpkin-protocol/src/java/client/play/chunk_batch_end.rs b/pumpkin-protocol/src/java/client/play/chunk_batch_end.rs index 2dade8e44..ed700798c 100644 --- a/pumpkin-protocol/src/java/client/play/chunk_batch_end.rs +++ b/pumpkin-protocol/src/java/client/play/chunk_batch_end.rs @@ -17,6 +17,7 @@ pub struct CChunkBatchEnd { } impl CChunkBatchEnd { + #[must_use] pub fn new(count: u16) -> Self { Self { batch_size: count.into(), diff --git a/pumpkin-protocol/src/java/client/play/chunk_data.rs b/pumpkin-protocol/src/java/client/play/chunk_data.rs index 3b1fdfe74..df7fd7bf5 100644 --- a/pumpkin-protocol/src/java/client/play/chunk_data.rs +++ b/pumpkin-protocol/src/java/client/play/chunk_data.rs @@ -19,6 +19,7 @@ use std::io::Write; pub struct CChunkData<'a>(pub &'a ChunkData); impl ClientPacket for CChunkData<'_> { + #[expect(clippy::too_many_lines)] fn write_packet_data( &self, write: impl Write, @@ -116,7 +117,7 @@ impl ClientPacket for CChunkData<'_> { )) })?)?; write.write_slice(&blocks_and_biomes_buf)?; - } + }; write.write_var_int(&VarInt(self.0.block_entities.len() as i32))?; for block_entity in self.0.block_entities.values() { diff --git a/pumpkin-protocol/src/java/client/play/clear_title.rs b/pumpkin-protocol/src/java/client/play/clear_title.rs index 25f2a060b..2a2ecb9db 100644 --- a/pumpkin-protocol/src/java/client/play/clear_title.rs +++ b/pumpkin-protocol/src/java/client/play/clear_title.rs @@ -18,6 +18,7 @@ pub struct CClearTitle { } impl CClearTitle { + #[must_use] pub const fn new(reset: bool) -> Self { Self { reset } } diff --git a/pumpkin-protocol/src/java/client/play/close_container.rs b/pumpkin-protocol/src/java/client/play/close_container.rs index 1731d7baf..5d156b12e 100644 --- a/pumpkin-protocol/src/java/client/play/close_container.rs +++ b/pumpkin-protocol/src/java/client/play/close_container.rs @@ -19,6 +19,7 @@ pub struct CCloseContainer { pub sync_id: VarInt, } impl CCloseContainer { + #[must_use] pub const fn new(window_id: VarInt) -> Self { Self { sync_id: window_id } } diff --git a/pumpkin-protocol/src/java/client/play/combat_death.rs b/pumpkin-protocol/src/java/client/play/combat_death.rs index 42df278e4..bf9f30df8 100644 --- a/pumpkin-protocol/src/java/client/play/combat_death.rs +++ b/pumpkin-protocol/src/java/client/play/combat_death.rs @@ -19,6 +19,7 @@ pub struct CCombatDeath<'a> { } impl<'a> CCombatDeath<'a> { + #[must_use] pub fn new(player_id: VarInt, message: &'a TextComponent) -> Self { Self { player_id, message } } diff --git a/pumpkin-protocol/src/java/client/play/command_suggestions.rs b/pumpkin-protocol/src/java/client/play/command_suggestions.rs index d31cc739a..c61946920 100644 --- a/pumpkin-protocol/src/java/client/play/command_suggestions.rs +++ b/pumpkin-protocol/src/java/client/play/command_suggestions.rs @@ -28,6 +28,7 @@ pub struct CCommandSuggestions { } impl CCommandSuggestions { + #[must_use] pub fn new( id: VarInt, start: VarInt, @@ -50,6 +51,7 @@ pub struct CommandSuggestion { } impl CommandSuggestion { + #[must_use] pub fn new(suggestion: String, tooltip: Option) -> Self { Self { suggestion, diff --git a/pumpkin-protocol/src/java/client/play/commands.rs b/pumpkin-protocol/src/java/client/play/commands.rs index 8af1cd9ca..37a3dd146 100644 --- a/pumpkin-protocol/src/java/client/play/commands.rs +++ b/pumpkin-protocol/src/java/client/play/commands.rs @@ -22,6 +22,7 @@ pub struct CCommands<'a> { } impl<'a> CCommands<'a> { + #[must_use] pub fn new(nodes: Box<[ProtoNode<'a>]>, root_node_index: VarInt) -> Self { Self { nodes, @@ -79,7 +80,7 @@ impl ProtoNode<'_> { } => { let mut n = 1; if is_executable { - n |= Self::FLAG_IS_EXECUTABLE + n |= Self::FLAG_IS_EXECUTABLE; } n } @@ -91,10 +92,10 @@ impl ProtoNode<'_> { } => { let mut n = 2; if override_suggestion_type.is_some() { - n |= Self::FLAG_HAS_SUGGESTION_TYPE + n |= Self::FLAG_HAS_SUGGESTION_TYPE; } if is_executable { - n |= Self::FLAG_IS_EXECUTABLE + n |= Self::FLAG_IS_EXECUTABLE; } n } @@ -219,10 +220,11 @@ impl ArgumentType<'_> { pub const SCORE_HOLDER_FLAG_ALLOW_MULTIPLE: u8 = 1; + #[expect(clippy::match_same_arms)] pub fn write_to_buffer(&self, write: &mut impl Write) -> Result<(), WritingError> { // Safety: Since Self is repr(u32), it is guaranteed to hold the discriminant in the first 4 bytes // See https://doc.rust-lang.org/reference/items/enumerations.html#pointer-casting - let id = unsafe { *(self as *const Self as *const i32) }; + let id = unsafe { *std::ptr::from_ref::(self).cast::() }; write.write_var_int(&(id).into())?; match self { Self::Float { min, max } => Self::write_number_arg(*min, *max, write), @@ -255,10 +257,10 @@ impl ArgumentType<'_> { ) -> Result<(), WritingError> { let mut flags: u8 = 0; if min.is_some() { - flags |= 1 + flags |= 1; } if max.is_some() { - flags |= 2 + flags |= 2; } write.write_u8(flags)?; @@ -329,7 +331,7 @@ pub enum SuggestionProviders { } impl SuggestionProviders { - fn resource_location(&self) -> &'static str { + fn resource_location(self) -> &'static str { match self { Self::AskServer => "minecraft:ask_server", Self::AllRecipes => "minecraft:all_recipes", diff --git a/pumpkin-protocol/src/java/client/play/cookie_request.rs b/pumpkin-protocol/src/java/client/play/cookie_request.rs index 914da5c85..950cab94f 100644 --- a/pumpkin-protocol/src/java/client/play/cookie_request.rs +++ b/pumpkin-protocol/src/java/client/play/cookie_request.rs @@ -16,6 +16,7 @@ pub struct CPlayCookieRequest<'a> { } impl<'a> CPlayCookieRequest<'a> { + #[must_use] pub fn new(key: &'a ResourceLocation) -> Self { Self { key } } diff --git a/pumpkin-protocol/src/java/client/play/damage_event.rs b/pumpkin-protocol/src/java/client/play/damage_event.rs index fe9692c39..537138211 100644 --- a/pumpkin-protocol/src/java/client/play/damage_event.rs +++ b/pumpkin-protocol/src/java/client/play/damage_event.rs @@ -31,6 +31,7 @@ pub struct CDamageEvent { } impl CDamageEvent { + #[must_use] pub fn new( entity_id: VarInt, source_type_id: VarInt, diff --git a/pumpkin-protocol/src/java/client/play/disconnect.rs b/pumpkin-protocol/src/java/client/play/disconnect.rs index cd2877bb1..748789738 100644 --- a/pumpkin-protocol/src/java/client/play/disconnect.rs +++ b/pumpkin-protocol/src/java/client/play/disconnect.rs @@ -18,6 +18,7 @@ pub struct CPlayDisconnect<'a> { } impl<'a> CPlayDisconnect<'a> { + #[must_use] pub fn new(reason: &'a TextComponent) -> Self { Self { reason } } diff --git a/pumpkin-protocol/src/java/client/play/disguised_chat_message.rs b/pumpkin-protocol/src/java/client/play/disguised_chat_message.rs index 719d770fc..65e699d14 100644 --- a/pumpkin-protocol/src/java/client/play/disguised_chat_message.rs +++ b/pumpkin-protocol/src/java/client/play/disguised_chat_message.rs @@ -26,6 +26,7 @@ pub struct CDisguisedChatMessage<'a> { } impl<'a> CDisguisedChatMessage<'a> { + #[must_use] pub fn new( message: &'a TextComponent, chat_type: VarInt, diff --git a/pumpkin-protocol/src/java/client/play/display_objective.rs b/pumpkin-protocol/src/java/client/play/display_objective.rs index 48ccf736f..74fc7f7ae 100644 --- a/pumpkin-protocol/src/java/client/play/display_objective.rs +++ b/pumpkin-protocol/src/java/client/play/display_objective.rs @@ -22,6 +22,7 @@ pub struct CDisplayObjective { } impl CDisplayObjective { + #[must_use] pub fn new(position: ScoreboardDisplaySlot, score_name: String) -> Self { Self { position: VarInt(position as i32), diff --git a/pumpkin-protocol/src/java/client/play/entity_animation.rs b/pumpkin-protocol/src/java/client/play/entity_animation.rs index 2394463cb..27207a517 100644 --- a/pumpkin-protocol/src/java/client/play/entity_animation.rs +++ b/pumpkin-protocol/src/java/client/play/entity_animation.rs @@ -19,6 +19,7 @@ pub struct CEntityAnimation { } impl CEntityAnimation { + #[must_use] pub fn new(entity_id: VarInt, animation: Animation) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/entity_metadata.rs b/pumpkin-protocol/src/java/client/play/entity_metadata.rs index 9e29f7135..8b674b47b 100644 --- a/pumpkin-protocol/src/java/client/play/entity_metadata.rs +++ b/pumpkin-protocol/src/java/client/play/entity_metadata.rs @@ -12,7 +12,7 @@ use crate::{ /// Updates the "Data Tracker" values for an entity. /// -/// Entity Metadata (or DataWatchers) controls persistent visual states that +/// Entity Metadata (or `DataWatchers`) controls persistent visual states that /// don't require a full packet to update, such as whether an entity is on fire, /// crouching, glowing, or the custom name displayed above its head. #[derive(Serialize)] @@ -27,6 +27,7 @@ pub struct CSetEntityMetadata { } impl CSetEntityMetadata { + #[must_use] pub fn new(entity_id: VarInt, metadata: Box<[u8]>) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/entity_position_sync.rs b/pumpkin-protocol/src/java/client/play/entity_position_sync.rs index 80c559786..83806f58b 100644 --- a/pumpkin-protocol/src/java/client/play/entity_position_sync.rs +++ b/pumpkin-protocol/src/java/client/play/entity_position_sync.rs @@ -32,6 +32,7 @@ pub struct CEntityPositionSync { } impl CEntityPositionSync { + #[must_use] pub fn new( entity_id: VarInt, position: Vector3, diff --git a/pumpkin-protocol/src/java/client/play/entity_sound_effect.rs b/pumpkin-protocol/src/java/client/play/entity_sound_effect.rs index c733782ea..21f02ba55 100644 --- a/pumpkin-protocol/src/java/client/play/entity_sound_effect.rs +++ b/pumpkin-protocol/src/java/client/play/entity_sound_effect.rs @@ -12,7 +12,7 @@ use crate::{IdOr, SoundEvent, VarInt}; #[derive(Serialize)] #[java_packet(PLAY_SOUND_ENTITY)] pub struct CEntitySoundEffect { - /// The sound to play. Can be a hardcoded ID or a custom SoundEvent + /// The sound to play. Can be a hardcoded ID or a custom `SoundEvent` /// (Resource Location). pub sound_event: IdOr, /// The category of the sound (e.g., Master, Music, Weather, Players). @@ -30,6 +30,7 @@ pub struct CEntitySoundEffect { } impl CEntitySoundEffect { + #[must_use] pub fn new( sound_event: IdOr, sound_category: SoundCategory, diff --git a/pumpkin-protocol/src/java/client/play/entity_status.rs b/pumpkin-protocol/src/java/client/play/entity_status.rs index eb5f6fbbc..4ccd280fe 100644 --- a/pumpkin-protocol/src/java/client/play/entity_status.rs +++ b/pumpkin-protocol/src/java/client/play/entity_status.rs @@ -19,6 +19,7 @@ pub struct CEntityStatus { } impl CEntityStatus { + #[must_use] pub fn new(entity_id: i32, entity_status: i8) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/entity_velocity.rs b/pumpkin-protocol/src/java/client/play/entity_velocity.rs index dfc61c160..b0606412d 100644 --- a/pumpkin-protocol/src/java/client/play/entity_velocity.rs +++ b/pumpkin-protocol/src/java/client/play/entity_velocity.rs @@ -19,6 +19,7 @@ pub struct CEntityVelocity { } impl CEntityVelocity { + #[must_use] pub fn new(entity_id: VarInt, velocity: Vector3) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/explode.rs b/pumpkin-protocol/src/java/client/play/explode.rs index f809c20fa..2cbc7d793 100644 --- a/pumpkin-protocol/src/java/client/play/explode.rs +++ b/pumpkin-protocol/src/java/client/play/explode.rs @@ -34,6 +34,7 @@ pub struct CExplosion { } impl CExplosion { + #[must_use] pub fn new( center: Vector3, radius: f32, diff --git a/pumpkin-protocol/src/java/client/play/game_event.rs b/pumpkin-protocol/src/java/client/play/game_event.rs index e11d260a7..10835079d 100644 --- a/pumpkin-protocol/src/java/client/play/game_event.rs +++ b/pumpkin-protocol/src/java/client/play/game_event.rs @@ -18,6 +18,7 @@ pub struct CGameEvent { /// You need to implement all the random stuff somewhere, right? impl CGameEvent { + #[must_use] pub fn new(event: GameEvent, value: f32) -> Self { Self { event: event as u8, diff --git a/pumpkin-protocol/src/java/client/play/head_rot.rs b/pumpkin-protocol/src/java/client/play/head_rot.rs index f670b7e9d..93590d0bf 100644 --- a/pumpkin-protocol/src/java/client/play/head_rot.rs +++ b/pumpkin-protocol/src/java/client/play/head_rot.rs @@ -20,6 +20,7 @@ pub struct CHeadRot { } impl CHeadRot { + #[must_use] pub fn new(entity_id: VarInt, head_yaw: u8) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/hurt_animation.rs b/pumpkin-protocol/src/java/client/play/hurt_animation.rs index 154bdd3bb..786be9fc3 100644 --- a/pumpkin-protocol/src/java/client/play/hurt_animation.rs +++ b/pumpkin-protocol/src/java/client/play/hurt_animation.rs @@ -20,6 +20,7 @@ pub struct CHurtAnimation { } impl CHurtAnimation { + #[must_use] pub fn new(entity_id: VarInt, yaw: f32) -> Self { Self { entity_id, yaw } } diff --git a/pumpkin-protocol/src/java/client/play/initialize_world_border.rs b/pumpkin-protocol/src/java/client/play/initialize_world_border.rs index 9d6a562be..692199413 100644 --- a/pumpkin-protocol/src/java/client/play/initialize_world_border.rs +++ b/pumpkin-protocol/src/java/client/play/initialize_world_border.rs @@ -34,6 +34,7 @@ pub struct CInitializeWorldBorder { impl CInitializeWorldBorder { #[expect(clippy::too_many_arguments)] + #[must_use] pub fn new( x: f64, z: f64, diff --git a/pumpkin-protocol/src/java/client/play/keep_alive.rs b/pumpkin-protocol/src/java/client/play/keep_alive.rs index e787e2d70..18048bd93 100644 --- a/pumpkin-protocol/src/java/client/play/keep_alive.rs +++ b/pumpkin-protocol/src/java/client/play/keep_alive.rs @@ -17,6 +17,7 @@ pub struct CKeepAlive { } impl CKeepAlive { + #[must_use] pub fn new(keep_alive_id: i64) -> Self { Self { keep_alive_id } } diff --git a/pumpkin-protocol/src/java/client/play/level_event.rs b/pumpkin-protocol/src/java/client/play/level_event.rs index 1a397f02d..079d4c4b0 100644 --- a/pumpkin-protocol/src/java/client/play/level_event.rs +++ b/pumpkin-protocol/src/java/client/play/level_event.rs @@ -26,6 +26,7 @@ pub struct CLevelEvent { } impl CLevelEvent { + #[must_use] pub fn new(event: i32, location: BlockPos, data: i32, disable_relative_volume: bool) -> Self { Self { event, diff --git a/pumpkin-protocol/src/java/client/play/login.rs b/pumpkin-protocol/src/java/client/play/login.rs index fe66478d6..cb514dfc1 100644 --- a/pumpkin-protocol/src/java/client/play/login.rs +++ b/pumpkin-protocol/src/java/client/play/login.rs @@ -54,6 +54,8 @@ pub struct CLogin<'a> { impl<'a> CLogin<'a> { #[expect(clippy::too_many_arguments)] + #[expect(clippy::fn_params_excessive_bools)] + #[must_use] pub fn new( entity_id: i32, is_hardcore: bool, diff --git a/pumpkin-protocol/src/java/client/play/multi_block_update.rs b/pumpkin-protocol/src/java/client/play/multi_block_update.rs index a9e9e2268..c647c4bdf 100644 --- a/pumpkin-protocol/src/java/client/play/multi_block_update.rs +++ b/pumpkin-protocol/src/java/client/play/multi_block_update.rs @@ -1,7 +1,7 @@ use pumpkin_data::packet::clientbound::PLAY_SECTION_BLOCKS_UPDATE; use pumpkin_util::math::{ position::{BlockPos, chunk_section_from_pos, pack_local_chunk_section}, - vector3::{self, Vector3}, + vector3::{self}, }; use pumpkin_macros::java_packet; @@ -16,45 +16,45 @@ use crate::codec::{var_int::VarInt, var_long::VarLong}; /// (e.g., explosions, structure generation, or large-scale terraforming). #[java_packet(PLAY_SECTION_BLOCKS_UPDATE)] pub struct CMultiBlockUpdate { - /// The coordinates of the chunk section being updated. - /// Calculated as (block_coord >> 4). - pub chunk_section: Vector3, - /// A list of relative positions and their new block state IDs. - /// The i16 encodes the relative position within the section. - pub positions_to_state_ids: Vec<(i16, i32)>, + /// Chunk section position (x << 42 | z << 20 | y) + pub chunk_section: i64, + /// Array of `VarLongs`: (Block State ID << 12 | Relative Position) + pub updates: Vec, } impl CMultiBlockUpdate { - pub fn new(positions_to_state_ids: Vec<(BlockPos, u16)>) -> Self { - let chunk_section = chunk_section_from_pos(&positions_to_state_ids[0].0); + #[must_use] + pub fn new(updates: &[(BlockPos, u16)]) -> Self { + let first_pos = updates[0].0; + + let chunk_section_vec = chunk_section_from_pos(&first_pos); + let chunk_section = vector3::packed_chunk_pos(&chunk_section_vec); + + let packed_updates = updates + .iter() + .map(|(pos, state_id)| { + let local_pos = pack_local_chunk_section(pos) as u64; + let packed = (u64::from(*state_id) << 12) | (local_pos & 0xFFF); + VarLong(packed as i64) + }) + .collect(); + Self { chunk_section, - positions_to_state_ids: positions_to_state_ids - .into_iter() - .map(|(position, state_id)| (pack_local_chunk_section(&position), state_id as i32)) - .collect(), + updates: packed_updates, } } } impl Serialize for CMultiBlockUpdate { fn serialize(&self, serializer: S) -> Result { - let mut tuple = serializer.serialize_tuple(2 + self.positions_to_state_ids.len())?; + let mut tuple = serializer.serialize_tuple(2 + self.updates.len())?; - tuple.serialize_element(&vector3::packed_chunk_pos(&self.chunk_section))?; - tuple.serialize_element(&VarInt( - self.positions_to_state_ids.len().try_into().map_err(|_| { - serde::ser::Error::custom(format!( - "{} is not representable as a VarInt!", - self.positions_to_state_ids.len() - )) - })?, - ))?; + tuple.serialize_element(&self.chunk_section)?; + tuple.serialize_element(&VarInt(self.updates.len() as i32))?; - for (position, state_id) in &self.positions_to_state_ids { - let long = (*state_id as u64) << 12 | (*position as u64); - let var_long = VarLong::from(long as i64); - tuple.serialize_element(&var_long)?; + for update in &self.updates { + tuple.serialize_element(update)?; } tuple.end() diff --git a/pumpkin-protocol/src/java/client/play/open_screen.rs b/pumpkin-protocol/src/java/client/play/open_screen.rs index 8376ad087..9c9d62e2f 100644 --- a/pumpkin-protocol/src/java/client/play/open_screen.rs +++ b/pumpkin-protocol/src/java/client/play/open_screen.rs @@ -27,6 +27,7 @@ pub struct COpenScreen<'a> { } impl<'a> COpenScreen<'a> { + #[must_use] pub fn new(window_id: VarInt, window_type: VarInt, window_title: &'a TextComponent) -> Self { Self { sync_id: window_id, diff --git a/pumpkin-protocol/src/java/client/play/open_sign_editor.rs b/pumpkin-protocol/src/java/client/play/open_sign_editor.rs index c76d1a690..dd9920b3e 100644 --- a/pumpkin-protocol/src/java/client/play/open_sign_editor.rs +++ b/pumpkin-protocol/src/java/client/play/open_sign_editor.rs @@ -19,6 +19,7 @@ pub struct COpenSignEditor { } impl COpenSignEditor { + #[must_use] pub fn new(location: BlockPos, is_front_text: bool) -> Self { Self { location, diff --git a/pumpkin-protocol/src/java/client/play/particle.rs b/pumpkin-protocol/src/java/client/play/particle.rs index 4d7e5bd3f..aff45607e 100644 --- a/pumpkin-protocol/src/java/client/play/particle.rs +++ b/pumpkin-protocol/src/java/client/play/particle.rs @@ -38,6 +38,7 @@ pub struct CParticle<'a> { impl<'a> CParticle<'a> { #[expect(clippy::too_many_arguments)] + #[must_use] pub fn new( force_spawn: bool, important: bool, diff --git a/pumpkin-protocol/src/java/client/play/ping_response.rs b/pumpkin-protocol/src/java/client/play/ping_response.rs index 107ba6e89..a89be8794 100644 --- a/pumpkin-protocol/src/java/client/play/ping_response.rs +++ b/pumpkin-protocol/src/java/client/play/ping_response.rs @@ -12,6 +12,7 @@ pub struct CPingResponse { } impl CPingResponse { + #[must_use] pub fn new(payload: i64) -> Self { Self { payload } } diff --git a/pumpkin-protocol/src/java/client/play/player_abilities.rs b/pumpkin-protocol/src/java/client/play/player_abilities.rs index 000b8e0b1..2782dbd4d 100644 --- a/pumpkin-protocol/src/java/client/play/player_abilities.rs +++ b/pumpkin-protocol/src/java/client/play/player_abilities.rs @@ -25,6 +25,7 @@ pub struct CPlayerAbilities { } impl CPlayerAbilities { + #[must_use] pub fn new(flags: i8, flying_speed: f32, field_of_view: f32) -> Self { Self { flags, diff --git a/pumpkin-protocol/src/java/client/play/player_chat_message.rs b/pumpkin-protocol/src/java/client/play/player_chat_message.rs index effe072f3..05ad038d6 100644 --- a/pumpkin-protocol/src/java/client/play/player_chat_message.rs +++ b/pumpkin-protocol/src/java/client/play/player_chat_message.rs @@ -41,7 +41,7 @@ pub struct CPlayerChatMessage { /// Indicates if the message should be hidden or partially masked /// by the client's profanity filter. pub filter_type: FilterType, - /// ID of the chat type registry entry (e.g., "chat", "say_command"). + /// ID of the chat type registry entry (e.g., "chat", "`say_command`"). /// Usually `(index + 1)`. pub chat_type: VarInt, /// The display name of the sender. @@ -52,6 +52,7 @@ pub struct CPlayerChatMessage { impl CPlayerChatMessage { #[expect(clippy::too_many_arguments)] + #[must_use] pub fn new( global_index: VarInt, sender: uuid::Uuid, diff --git a/pumpkin-protocol/src/java/client/play/player_info_update.rs b/pumpkin-protocol/src/java/client/play/player_info_update.rs index 694cb8c2e..0952e0d4b 100644 --- a/pumpkin-protocol/src/java/client/play/player_info_update.rs +++ b/pumpkin-protocol/src/java/client/play/player_info_update.rs @@ -42,7 +42,7 @@ bitflags! { /// server only sends the fields specified in the `actions` bitmask. #[java_packet(PLAY_PLAYER_INFO_UPDATE)] pub struct CPlayerInfoUpdate<'a> { - /// The bitmask (PlayerInfoFlags) determining which data follows. + /// The bitmask (`PlayerInfoFlags`) determining which data follows. pub actions: u8, /// The list of players being updated. Each player entry contains /// data fields in the order they appear in the bitmask. @@ -55,6 +55,7 @@ pub struct Player<'a> { } impl<'a> CPlayerInfoUpdate<'a> { + #[must_use] pub fn new(actions: u8, players: &'a [Player<'a>]) -> Self { Self { actions, players } } diff --git a/pumpkin-protocol/src/java/client/play/player_position.rs b/pumpkin-protocol/src/java/client/play/player_position.rs index b6a0cb22f..11c8412f7 100644 --- a/pumpkin-protocol/src/java/client/play/player_position.rs +++ b/pumpkin-protocol/src/java/client/play/player_position.rs @@ -32,6 +32,7 @@ pub struct CPlayerPosition { } impl CPlayerPosition { + #[must_use] pub fn new( teleport_id: VarInt, position: Vector3, diff --git a/pumpkin-protocol/src/java/client/play/player_remove.rs b/pumpkin-protocol/src/java/client/play/player_remove.rs index 860b8f37f..3f2ddedcd 100644 --- a/pumpkin-protocol/src/java/client/play/player_remove.rs +++ b/pumpkin-protocol/src/java/client/play/player_remove.rs @@ -18,6 +18,7 @@ pub struct CRemovePlayerInfo<'a> { } impl<'a> CRemovePlayerInfo<'a> { + #[must_use] pub fn new(players: &'a [uuid::Uuid]) -> Self { Self { players } } diff --git a/pumpkin-protocol/src/java/client/play/player_spawn_position.rs b/pumpkin-protocol/src/java/client/play/player_spawn_position.rs index 99b2585c6..3d766bbc7 100644 --- a/pumpkin-protocol/src/java/client/play/player_spawn_position.rs +++ b/pumpkin-protocol/src/java/client/play/player_spawn_position.rs @@ -27,12 +27,13 @@ pub struct CPlayerSpawnPosition { } impl CPlayerSpawnPosition { + #[must_use] pub fn new(location: BlockPos, yaw: f32, pitch: f32, dimension_name: String) -> Self { Self { + dimension_name, location, yaw, pitch, - dimension_name, } } } diff --git a/pumpkin-protocol/src/java/client/play/remove_entities.rs b/pumpkin-protocol/src/java/client/play/remove_entities.rs index 970440d9c..568b93e12 100644 --- a/pumpkin-protocol/src/java/client/play/remove_entities.rs +++ b/pumpkin-protocol/src/java/client/play/remove_entities.rs @@ -16,6 +16,7 @@ pub struct CRemoveEntities<'a> { } impl<'a> CRemoveEntities<'a> { + #[must_use] pub fn new(entity_ids: &'a [VarInt]) -> Self { Self { entity_ids } } diff --git a/pumpkin-protocol/src/java/client/play/remove_mob_effect.rs b/pumpkin-protocol/src/java/client/play/remove_mob_effect.rs index c2489f041..a4f83b04a 100644 --- a/pumpkin-protocol/src/java/client/play/remove_mob_effect.rs +++ b/pumpkin-protocol/src/java/client/play/remove_mob_effect.rs @@ -11,6 +11,7 @@ pub struct CRemoveMobEffect { } impl CRemoveMobEffect { + #[must_use] pub fn new(entity_id: VarInt, effect_id: VarInt) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/reset_score.rs b/pumpkin-protocol/src/java/client/play/reset_score.rs index 7a0b04ae7..f9ad4cc29 100644 --- a/pumpkin-protocol/src/java/client/play/reset_score.rs +++ b/pumpkin-protocol/src/java/client/play/reset_score.rs @@ -10,6 +10,7 @@ pub struct CResetScore { } impl CResetScore { + #[must_use] pub fn new(entity_name: String, objective_name: Option) -> Self { Self { entity_name, diff --git a/pumpkin-protocol/src/java/client/play/respawn.rs b/pumpkin-protocol/src/java/client/play/respawn.rs index d02b5124f..1aebfe1c8 100644 --- a/pumpkin-protocol/src/java/client/play/respawn.rs +++ b/pumpkin-protocol/src/java/client/play/respawn.rs @@ -23,6 +23,7 @@ pub struct CRespawn { impl CRespawn { #[expect(clippy::too_many_arguments)] + #[must_use] pub fn new( dimension_type: VarInt, dimension_name: ResourceLocation, diff --git a/pumpkin-protocol/src/java/client/play/server_links.rs b/pumpkin-protocol/src/java/client/play/server_links.rs index 7203a81dd..afc0f8690 100644 --- a/pumpkin-protocol/src/java/client/play/server_links.rs +++ b/pumpkin-protocol/src/java/client/play/server_links.rs @@ -10,6 +10,7 @@ pub struct CPlayServerLinks<'a> { } impl<'a> CPlayServerLinks<'a> { + #[must_use] pub fn new(links: &'a [Link<'a>]) -> Self { Self { links } } diff --git a/pumpkin-protocol/src/java/client/play/set_border_center.rs b/pumpkin-protocol/src/java/client/play/set_border_center.rs index 54d0894a6..6190a3649 100644 --- a/pumpkin-protocol/src/java/client/play/set_border_center.rs +++ b/pumpkin-protocol/src/java/client/play/set_border_center.rs @@ -10,6 +10,7 @@ pub struct CSetBorderCenter { } impl CSetBorderCenter { + #[must_use] pub fn new(x: f64, z: f64) -> Self { Self { x, z } } diff --git a/pumpkin-protocol/src/java/client/play/set_border_lerp_size.rs b/pumpkin-protocol/src/java/client/play/set_border_lerp_size.rs index d9fc05dda..f998f874c 100644 --- a/pumpkin-protocol/src/java/client/play/set_border_lerp_size.rs +++ b/pumpkin-protocol/src/java/client/play/set_border_lerp_size.rs @@ -13,6 +13,7 @@ pub struct CSetBorderLerpSize { } impl CSetBorderLerpSize { + #[must_use] pub fn new(old_diameter: f64, new_diameter: f64, speed: VarLong) -> Self { Self { old_diameter, diff --git a/pumpkin-protocol/src/java/client/play/set_border_size.rs b/pumpkin-protocol/src/java/client/play/set_border_size.rs index 8d8169078..8b1ff4d0e 100644 --- a/pumpkin-protocol/src/java/client/play/set_border_size.rs +++ b/pumpkin-protocol/src/java/client/play/set_border_size.rs @@ -9,6 +9,7 @@ pub struct CSetBorderSize { } impl CSetBorderSize { + #[must_use] pub fn new(diameter: f64) -> Self { Self { diameter } } diff --git a/pumpkin-protocol/src/java/client/play/set_border_warning_delay.rs b/pumpkin-protocol/src/java/client/play/set_border_warning_delay.rs index 0101389d7..4fd1616f0 100644 --- a/pumpkin-protocol/src/java/client/play/set_border_warning_delay.rs +++ b/pumpkin-protocol/src/java/client/play/set_border_warning_delay.rs @@ -11,6 +11,7 @@ pub struct CSetBorderWarningDelay { } impl CSetBorderWarningDelay { + #[must_use] pub fn new(warning_time: VarInt) -> Self { Self { warning_time } } diff --git a/pumpkin-protocol/src/java/client/play/set_border_warning_distance.rs b/pumpkin-protocol/src/java/client/play/set_border_warning_distance.rs index 4c31dbb45..f24b4785e 100644 --- a/pumpkin-protocol/src/java/client/play/set_border_warning_distance.rs +++ b/pumpkin-protocol/src/java/client/play/set_border_warning_distance.rs @@ -11,6 +11,7 @@ pub struct CSetBorderWarningDistance { } impl CSetBorderWarningDistance { + #[must_use] pub fn new(warning_blocks: VarInt) -> Self { Self { warning_blocks } } diff --git a/pumpkin-protocol/src/java/client/play/set_container_content.rs b/pumpkin-protocol/src/java/client/play/set_container_content.rs index 4c1ec4941..91f8c1e3d 100644 --- a/pumpkin-protocol/src/java/client/play/set_container_content.rs +++ b/pumpkin-protocol/src/java/client/play/set_container_content.rs @@ -15,6 +15,7 @@ pub struct CSetContainerContent<'a> { } impl<'a> CSetContainerContent<'a> { + #[must_use] pub fn new( window_id: VarInt, state_id: VarInt, diff --git a/pumpkin-protocol/src/java/client/play/set_container_property.rs b/pumpkin-protocol/src/java/client/play/set_container_property.rs index 3989f0d10..62a66a403 100644 --- a/pumpkin-protocol/src/java/client/play/set_container_property.rs +++ b/pumpkin-protocol/src/java/client/play/set_container_property.rs @@ -13,6 +13,7 @@ pub struct CSetContainerProperty { } impl CSetContainerProperty { + #[must_use] pub const fn new(window_id: VarInt, property: i16, value: i16) -> Self { Self { window_id, diff --git a/pumpkin-protocol/src/java/client/play/set_container_slot.rs b/pumpkin-protocol/src/java/client/play/set_container_slot.rs index 2abaca5c6..17f4e56fa 100644 --- a/pumpkin-protocol/src/java/client/play/set_container_slot.rs +++ b/pumpkin-protocol/src/java/client/play/set_container_slot.rs @@ -15,6 +15,7 @@ pub struct CSetContainerSlot<'a> { } impl<'a> CSetContainerSlot<'a> { + #[must_use] pub fn new( window_id: i8, state_id: i32, diff --git a/pumpkin-protocol/src/java/client/play/set_cursor_slot.rs b/pumpkin-protocol/src/java/client/play/set_cursor_slot.rs index 1731644ea..cffac2ce6 100644 --- a/pumpkin-protocol/src/java/client/play/set_cursor_slot.rs +++ b/pumpkin-protocol/src/java/client/play/set_cursor_slot.rs @@ -11,6 +11,7 @@ pub struct CSetCursorItem<'a> { } impl<'a> CSetCursorItem<'a> { + #[must_use] pub fn new(stack: &'a ItemStackSerializer<'a>) -> Self { Self { stack } } diff --git a/pumpkin-protocol/src/java/client/play/set_equipment.rs b/pumpkin-protocol/src/java/client/play/set_equipment.rs index 112e92e1a..740bda74f 100644 --- a/pumpkin-protocol/src/java/client/play/set_equipment.rs +++ b/pumpkin-protocol/src/java/client/play/set_equipment.rs @@ -21,6 +21,7 @@ pub struct CSetEquipment { } impl CSetEquipment { + #[must_use] pub fn new(entity_id: VarInt, equipment: Vec<(i8, ItemStackSerializer<'static>)>) -> Self { Self { entity_id, @@ -41,10 +42,10 @@ impl ClientPacket for CSetEquipment { for i in 0..self.equipment.len() { let equipment = &self.equipment[i]; let slot = &equipment.0; - if i != self.equipment.len() - 1 { - write.write_i8(*slot | -128)?; - } else { + if i == self.equipment.len() - 1 { write.write_i8(*slot)?; + } else { + write.write_i8(*slot | -128)?; } let mut serializer = Serializer::new(&mut write); equipment diff --git a/pumpkin-protocol/src/java/client/play/set_experience.rs b/pumpkin-protocol/src/java/client/play/set_experience.rs index 35b5d1185..a2ca5d0b0 100644 --- a/pumpkin-protocol/src/java/client/play/set_experience.rs +++ b/pumpkin-protocol/src/java/client/play/set_experience.rs @@ -13,11 +13,12 @@ pub struct CSetExperience { } impl CSetExperience { + #[must_use] pub fn new(progress: f32, level: VarInt, total_experience: VarInt) -> Self { Self { progress, - level, total_experience, + level, } } } diff --git a/pumpkin-protocol/src/java/client/play/set_health.rs b/pumpkin-protocol/src/java/client/play/set_health.rs index 5dca5985b..6f96aed0d 100644 --- a/pumpkin-protocol/src/java/client/play/set_health.rs +++ b/pumpkin-protocol/src/java/client/play/set_health.rs @@ -13,6 +13,7 @@ pub struct CSetHealth { } impl CSetHealth { + #[must_use] pub fn new(health: f32, food: VarInt, food_saturation: f32) -> Self { Self { health, diff --git a/pumpkin-protocol/src/java/client/play/set_held_item.rs b/pumpkin-protocol/src/java/client/play/set_held_item.rs index ee7c37c21..6a359d848 100644 --- a/pumpkin-protocol/src/java/client/play/set_held_item.rs +++ b/pumpkin-protocol/src/java/client/play/set_held_item.rs @@ -9,6 +9,7 @@ pub struct CSetSelectedSlot { } impl CSetSelectedSlot { + #[must_use] pub fn new(slot: i8) -> Self { Self { slot } } diff --git a/pumpkin-protocol/src/java/client/play/set_player_inventory.rs b/pumpkin-protocol/src/java/client/play/set_player_inventory.rs index a7895ada6..c73793352 100644 --- a/pumpkin-protocol/src/java/client/play/set_player_inventory.rs +++ b/pumpkin-protocol/src/java/client/play/set_player_inventory.rs @@ -13,6 +13,7 @@ pub struct CSetPlayerInventory<'a> { } impl<'a> CSetPlayerInventory<'a> { + #[must_use] pub fn new(slot: VarInt, item: &'a ItemStackSerializer<'a>) -> Self { Self { slot, item } } diff --git a/pumpkin-protocol/src/java/client/play/set_time.rs b/pumpkin-protocol/src/java/client/play/set_time.rs index f43d92098..21b57a9a6 100644 --- a/pumpkin-protocol/src/java/client/play/set_time.rs +++ b/pumpkin-protocol/src/java/client/play/set_time.rs @@ -11,6 +11,7 @@ pub struct CUpdateTime { } impl CUpdateTime { + #[must_use] pub fn new(world_age: i64, time_of_day: i64, time_of_day_increasing: bool) -> Self { Self { world_age, diff --git a/pumpkin-protocol/src/java/client/play/set_title.rs b/pumpkin-protocol/src/java/client/play/set_title.rs index 8e67dc555..61d33398f 100644 --- a/pumpkin-protocol/src/java/client/play/set_title.rs +++ b/pumpkin-protocol/src/java/client/play/set_title.rs @@ -11,6 +11,7 @@ pub struct CTitleText<'a> { } impl<'a> CTitleText<'a> { + #[must_use] pub fn new(title: &'a TextComponent) -> Self { Self { title } } diff --git a/pumpkin-protocol/src/java/client/play/set_title_animation.rs b/pumpkin-protocol/src/java/client/play/set_title_animation.rs index eba5a8345..07f85bb7c 100644 --- a/pumpkin-protocol/src/java/client/play/set_title_animation.rs +++ b/pumpkin-protocol/src/java/client/play/set_title_animation.rs @@ -12,6 +12,7 @@ pub struct CTitleAnimation { } impl CTitleAnimation { + #[must_use] pub fn new(fade_in_ticks: i32, stay_ticks: i32, fade_out_ticks: i32) -> Self { Self { fade_in_ticks, diff --git a/pumpkin-protocol/src/java/client/play/sound_effect.rs b/pumpkin-protocol/src/java/client/play/sound_effect.rs index 742b4dd4e..0d044ef7e 100644 --- a/pumpkin-protocol/src/java/client/play/sound_effect.rs +++ b/pumpkin-protocol/src/java/client/play/sound_effect.rs @@ -17,6 +17,7 @@ pub struct CSoundEffect { } impl CSoundEffect { + #[must_use] pub fn new( sound_event: IdOr, sound_category: SoundCategory, diff --git a/pumpkin-protocol/src/java/client/play/spawn_entity.rs b/pumpkin-protocol/src/java/client/play/spawn_entity.rs index 795755c2e..8222450a2 100644 --- a/pumpkin-protocol/src/java/client/play/spawn_entity.rs +++ b/pumpkin-protocol/src/java/client/play/spawn_entity.rs @@ -25,6 +25,7 @@ pub struct CSpawnEntity { impl CSpawnEntity { #[expect(clippy::too_many_arguments)] + #[must_use] pub fn new( entity_id: VarInt, entity_uuid: uuid::Uuid, diff --git a/pumpkin-protocol/src/java/client/play/stop_sound.rs b/pumpkin-protocol/src/java/client/play/stop_sound.rs index 193eb4aa1..cade760f5 100644 --- a/pumpkin-protocol/src/java/client/play/stop_sound.rs +++ b/pumpkin-protocol/src/java/client/play/stop_sound.rs @@ -15,6 +15,7 @@ pub struct CStopSound { } impl CStopSound { + #[must_use] pub fn new(sound_id: Option, category: Option) -> Self { Self { sound_id, category } } @@ -26,12 +27,11 @@ impl ClientPacket for CStopSound { write: impl Write, _version: &MinecraftVersion, ) -> Result<(), WritingError> { - let mut write = write; - const NO_CATEGORY_NO_SOUND: u8 = 0; const CATEGORY_ONLY: u8 = 1; const SOUND_ONLY: u8 = 2; const CATEGORY_AND_SOUND: u8 = 3; + let mut write = write; match (self.category, &self.sound_id) { (Some(category), Some(sound_id)) => { diff --git a/pumpkin-protocol/src/java/client/play/store_cookie.rs b/pumpkin-protocol/src/java/client/play/store_cookie.rs index 390329e4f..27d30799c 100644 --- a/pumpkin-protocol/src/java/client/play/store_cookie.rs +++ b/pumpkin-protocol/src/java/client/play/store_cookie.rs @@ -13,6 +13,7 @@ pub struct CStoreCookie<'a> { } impl<'a> CStoreCookie<'a> { + #[must_use] pub fn new(key: &'a ResourceLocation, payload: &'a [u8]) -> Self { Self { key, payload } } diff --git a/pumpkin-protocol/src/java/client/play/subtitle.rs b/pumpkin-protocol/src/java/client/play/subtitle.rs index 1c375cd2f..2a830a2f9 100644 --- a/pumpkin-protocol/src/java/client/play/subtitle.rs +++ b/pumpkin-protocol/src/java/client/play/subtitle.rs @@ -11,6 +11,7 @@ pub struct CSubtitle<'a> { } impl<'a> CSubtitle<'a> { + #[must_use] pub fn new(subtitle: &'a TextComponent) -> Self { Self { subtitle } } diff --git a/pumpkin-protocol/src/java/client/play/system_chat_message.rs b/pumpkin-protocol/src/java/client/play/system_chat_message.rs index ceab5daf9..480c30101 100644 --- a/pumpkin-protocol/src/java/client/play/system_chat_message.rs +++ b/pumpkin-protocol/src/java/client/play/system_chat_message.rs @@ -12,6 +12,7 @@ pub struct CSystemChatMessage<'a> { } impl<'a> CSystemChatMessage<'a> { + #[must_use] pub fn new(content: &'a TextComponent, overlay: bool) -> Self { Self { content, overlay } } diff --git a/pumpkin-protocol/src/java/client/play/take_item.rs b/pumpkin-protocol/src/java/client/play/take_item.rs index 5f6d2e6d0..0c27e7cb3 100644 --- a/pumpkin-protocol/src/java/client/play/take_item.rs +++ b/pumpkin-protocol/src/java/client/play/take_item.rs @@ -15,6 +15,7 @@ pub struct CTakeItemEntity { } impl CTakeItemEntity { + #[must_use] pub fn new(entity_id: VarInt, collector_entity_id: VarInt, stack_amount: VarInt) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/teleport_entity.rs b/pumpkin-protocol/src/java/client/play/teleport_entity.rs index cec9c0290..659778d06 100644 --- a/pumpkin-protocol/src/java/client/play/teleport_entity.rs +++ b/pumpkin-protocol/src/java/client/play/teleport_entity.rs @@ -19,6 +19,7 @@ pub struct CTeleportEntity<'a> { } impl<'a> CTeleportEntity<'a> { + #[must_use] pub fn new( entity_id: VarInt, position: Vector3, diff --git a/pumpkin-protocol/src/java/client/play/ticking_state.rs b/pumpkin-protocol/src/java/client/play/ticking_state.rs index 188a3eeeb..23986533f 100644 --- a/pumpkin-protocol/src/java/client/play/ticking_state.rs +++ b/pumpkin-protocol/src/java/client/play/ticking_state.rs @@ -10,6 +10,7 @@ pub struct CTickingState { } impl CTickingState { + #[must_use] pub fn new(tick_rate: f32, is_frozen: bool) -> Self { Self { tick_rate, diff --git a/pumpkin-protocol/src/java/client/play/ticking_step.rs b/pumpkin-protocol/src/java/client/play/ticking_step.rs index 50d7d2e57..fe527da17 100644 --- a/pumpkin-protocol/src/java/client/play/ticking_step.rs +++ b/pumpkin-protocol/src/java/client/play/ticking_step.rs @@ -11,6 +11,7 @@ pub struct CTickingStep { } impl CTickingStep { + #[must_use] pub fn new(tick_steps: VarInt) -> Self { Self { tick_steps } } diff --git a/pumpkin-protocol/src/java/client/play/transfer.rs b/pumpkin-protocol/src/java/client/play/transfer.rs index 2e0ebe0ac..d44c45c12 100644 --- a/pumpkin-protocol/src/java/client/play/transfer.rs +++ b/pumpkin-protocol/src/java/client/play/transfer.rs @@ -11,6 +11,7 @@ pub struct CTransfer<'a> { } impl<'a> CTransfer<'a> { + #[must_use] pub fn new(host: &'a str, port: VarInt) -> Self { Self { host, port } } diff --git a/pumpkin-protocol/src/java/client/play/unload_chunk.rs b/pumpkin-protocol/src/java/client/play/unload_chunk.rs index b461896c8..7adb98a60 100644 --- a/pumpkin-protocol/src/java/client/play/unload_chunk.rs +++ b/pumpkin-protocol/src/java/client/play/unload_chunk.rs @@ -10,6 +10,7 @@ pub struct CUnloadChunk { } impl CUnloadChunk { + #[must_use] pub fn new(x: i32, z: i32) -> Self { Self { z, x } } diff --git a/pumpkin-protocol/src/java/client/play/update_entity_pos.rs b/pumpkin-protocol/src/java/client/play/update_entity_pos.rs index 046185cc1..1f327ad75 100644 --- a/pumpkin-protocol/src/java/client/play/update_entity_pos.rs +++ b/pumpkin-protocol/src/java/client/play/update_entity_pos.rs @@ -14,6 +14,7 @@ pub struct CUpdateEntityPos { } impl CUpdateEntityPos { + #[must_use] pub fn new(entity_id: VarInt, delta: Vector3, on_ground: bool) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/update_entity_pos_rot.rs b/pumpkin-protocol/src/java/client/play/update_entity_pos_rot.rs index 8d05f25ad..7a63c1ae6 100644 --- a/pumpkin-protocol/src/java/client/play/update_entity_pos_rot.rs +++ b/pumpkin-protocol/src/java/client/play/update_entity_pos_rot.rs @@ -16,6 +16,7 @@ pub struct CUpdateEntityPosRot { } impl CUpdateEntityPosRot { + #[must_use] pub fn new( entity_id: VarInt, delta: Vector3, diff --git a/pumpkin-protocol/src/java/client/play/update_entity_rot.rs b/pumpkin-protocol/src/java/client/play/update_entity_rot.rs index 0a15c657c..374cde5dd 100644 --- a/pumpkin-protocol/src/java/client/play/update_entity_rot.rs +++ b/pumpkin-protocol/src/java/client/play/update_entity_rot.rs @@ -14,6 +14,7 @@ pub struct CUpdateEntityRot { } impl CUpdateEntityRot { + #[must_use] pub fn new(entity_id: VarInt, yaw: u8, pitch: u8, on_ground: bool) -> Self { Self { entity_id, diff --git a/pumpkin-protocol/src/java/client/play/update_mob_effect.rs b/pumpkin-protocol/src/java/client/play/update_mob_effect.rs index 8abc6e378..3630e2cd1 100644 --- a/pumpkin-protocol/src/java/client/play/update_mob_effect.rs +++ b/pumpkin-protocol/src/java/client/play/update_mob_effect.rs @@ -15,6 +15,7 @@ pub struct CUpdateMobEffect { } impl CUpdateMobEffect { + #[must_use] pub fn new( entity_id: VarInt, effect_id: VarInt, diff --git a/pumpkin-protocol/src/java/client/play/update_objectives.rs b/pumpkin-protocol/src/java/client/play/update_objectives.rs index cfe27ab19..7ad9f0cf9 100644 --- a/pumpkin-protocol/src/java/client/play/update_objectives.rs +++ b/pumpkin-protocol/src/java/client/play/update_objectives.rs @@ -16,6 +16,7 @@ pub struct CUpdateObjectives { } impl CUpdateObjectives { + #[must_use] pub fn new( objective_name: String, mode: Mode, diff --git a/pumpkin-protocol/src/java/client/play/update_score.rs b/pumpkin-protocol/src/java/client/play/update_score.rs index f1e1b9158..01a987be5 100644 --- a/pumpkin-protocol/src/java/client/play/update_score.rs +++ b/pumpkin-protocol/src/java/client/play/update_score.rs @@ -29,6 +29,7 @@ pub struct CUpdateScore { } impl CUpdateScore { + #[must_use] pub fn new( entity_name: String, objective_name: String, diff --git a/pumpkin-protocol/src/java/client/play/worldevent.rs b/pumpkin-protocol/src/java/client/play/worldevent.rs index 96b742b81..d67069bb8 100644 --- a/pumpkin-protocol/src/java/client/play/worldevent.rs +++ b/pumpkin-protocol/src/java/client/play/worldevent.rs @@ -27,6 +27,7 @@ pub struct CWorldEvent { } impl CWorldEvent { + #[must_use] pub fn new(event: i32, location: BlockPos, data: i32, disable_relative_volume: bool) -> Self { Self { event, diff --git a/pumpkin-protocol/src/java/client/status/ping_response.rs b/pumpkin-protocol/src/java/client/status/ping_response.rs index cbaee2e53..0db8ea37f 100644 --- a/pumpkin-protocol/src/java/client/status/ping_response.rs +++ b/pumpkin-protocol/src/java/client/status/ping_response.rs @@ -17,6 +17,7 @@ pub struct CPingResponse { } impl CPingResponse { + #[must_use] pub fn new(payload: i64) -> Self { Self { payload } } diff --git a/pumpkin-protocol/src/java/client/status/status_response.rs b/pumpkin-protocol/src/java/client/status/status_response.rs index 848ef84dc..6c3101445 100644 --- a/pumpkin-protocol/src/java/client/status/status_response.rs +++ b/pumpkin-protocol/src/java/client/status/status_response.rs @@ -16,6 +16,7 @@ pub struct CStatusResponse { pub json_response: String, } impl CStatusResponse { + #[must_use] pub fn new(json_response: String) -> Self { Self { json_response } } diff --git a/pumpkin-protocol/src/java/packet_decoder.rs b/pumpkin-protocol/src/java/packet_decoder.rs index 3aa4a8453..62a6a07c6 100644 --- a/pumpkin-protocol/src/java/packet_decoder.rs +++ b/pumpkin-protocol/src/java/packet_decoder.rs @@ -39,10 +39,11 @@ pub enum DecryptionReader { } impl DecryptionReader { + #[must_use] pub fn upgrade(self, cipher: Aes128Cfb8Dec) -> Self { match self { Self::None(stream) => Self::Decrypt(Box::new(StreamDecryptor::new(cipher, stream))), - _ => panic!("Cannot upgrade a stream that already has a cipher!"), + Self::Decrypt(_) => panic!("Cannot upgrade a stream that already has a cipher!"), } } } @@ -68,7 +69,7 @@ impl AsyncRead for DecryptionReader { } /// Decoder: Client -> Server -/// Supports ZLib decoding/decompression +/// Supports `ZLib` decoding/decompression /// Supports Aes128 Encryption pub struct TCPNetworkDecoder { reader: DecryptionReader, @@ -107,7 +108,7 @@ impl TCPNetworkDecoder { let packet_len = packet_len.0 as u64; if !(0..=MAX_PACKET_SIZE).contains(&packet_len) { - Err(PacketDecodeError::OutOfBounds)? + Err(PacketDecodeError::OutOfBounds)?; } let mut bounded_reader = (&mut self.reader).take(packet_len); @@ -118,7 +119,7 @@ impl TCPNetworkDecoder { let decompressed_length = decompressed_length.0 as usize; if !(0..=MAX_PACKET_DATA_SIZE).contains(&decompressed_length) { - Err(PacketDecodeError::TooLong)? + Err(PacketDecodeError::TooLong)?; } if decompressed_length > 0 { @@ -126,7 +127,7 @@ impl TCPNetworkDecoder { } else { // Validate that we are not less than the compression threshold if raw_packet_length > threshold as u64 { - Err(PacketDecodeError::NotCompressed)? + Err(PacketDecodeError::NotCompressed)?; } DecompressionReader::None(bounded_reader) @@ -219,11 +220,9 @@ mod tests { let packet_len = buffer.len() as i32; let packet_len_varint = VarInt(packet_len); let mut packet_length_encoded = Vec::new(); - { - packet_len_varint - .encode(&mut packet_length_encoded) - .unwrap(); - } + packet_len_varint + .encode(&mut packet_length_encoded) + .unwrap(); // Create a new buffer for the entire packet let mut packet = Vec::new(); @@ -233,10 +232,8 @@ mod tests { // Encrypt if key and IV are provided. if let (Some(k), Some(v)) = (key, iv) { encrypt_aes128(&mut packet, k, v); - packet - } else { - packet } + packet } /// Test decoding without compression and encryption @@ -362,9 +359,7 @@ mod tests { // Attempt to decode and expect a decompression error let result = decoder.get_raw_packet().await; - if result.is_ok() { - panic!("This should have errored!"); - } + assert!(result.is_err(), "This should have errored!"); } /// Test decoding with a zero-length packet @@ -388,6 +383,7 @@ mod tests { /// Test decoding with maximum length packet #[tokio::test] + #[expect(clippy::print_stdout)] async fn test_decode_with_maximum_length_packet() { // Sample packet data: packet_id = 8, payload = "A" repeated MAX_PACKET_SIZE times // Sample packet data: packet_id = 8, payload = "A" repeated (MAX_PACKET_SIZE - 1) times diff --git a/pumpkin-protocol/src/java/packet_encoder.rs b/pumpkin-protocol/src/java/packet_encoder.rs index dd5c60304..e1e6f1cd0 100644 --- a/pumpkin-protocol/src/java/packet_encoder.rs +++ b/pumpkin-protocol/src/java/packet_encoder.rs @@ -17,10 +17,11 @@ pub enum EncryptionWriter { } impl EncryptionWriter { + #[must_use] pub fn upgrade(self, cipher: Aes128Cfb8Enc) -> Self { match self { Self::None(stream) => Self::Encrypt(Box::new(StreamEncryptor::new(cipher, stream))), - _ => panic!("Cannot upgrade a stream that already has a cipher!"), + Self::Encrypt(_) => panic!("Cannot upgrade a stream that already has a cipher!"), } } } @@ -77,7 +78,7 @@ impl AsyncWrite for EncryptionWriter { } /// Encoder: Server -> Client -/// Supports ZLib endecoding/compression +/// Supports `ZLib` endecoding/compression /// Supports Aes128 Encryption pub struct TCPNetworkEncoder { writer: EncryptionWriter, @@ -114,20 +115,20 @@ impl TCPNetworkEncoder { /// /// **Uncompressed:** /// |-----------------------| - /// | Packet Length (VarInt)| + /// | Packet Length (`VarInt`)| /// |-----------------------| - /// | Packet ID (VarInt) | + /// | Packet ID (`VarInt`) | /// |-----------------------| /// | Data (Byte Array) | /// |-----------------------| /// /// **Compressed:** /// |------------------------| - /// | Packet Length (VarInt) | + /// | Packet Length (`VarInt`) | /// |------------------------| - /// | Data Length (VarInt) | + /// | Data Length (`VarInt`) | /// |------------------------| - /// | Packet ID (VarInt) | + /// | Packet ID (`VarInt`) | /// |------------------------| /// | Data (Byte Array) | /// |------------------------| @@ -533,7 +534,7 @@ mod tests { #[tokio::test] async fn test_encode_with_zero_length_payload() { // Create a CStatusResponse packet with empty payload - let packet = CStatusResponse::new(String::from("")); + let packet = CStatusResponse::new(String::new()); // Build the packet without compression and encryption let packet_bytes = build_packet_with_encoder(&packet, None, None).await; @@ -609,7 +610,7 @@ mod tests { assert_eq!(buffer, expected_payload); } - /// Test encoding a packet that exceeds MAX_PACKET_SIZE as usize + /// Test encoding a packet that exceeds `MAX_PACKET_SIZE` as usize #[tokio::test] #[should_panic(expected = "TooLong")] async fn test_encode_packet_exceeding_maximum_size() { diff --git a/pumpkin-protocol/src/java/server/config/client_information.rs b/pumpkin-protocol/src/java/server/config/client_information.rs index b2b98d95c..b96be1b2c 100644 --- a/pumpkin-protocol/src/java/server/config/client_information.rs +++ b/pumpkin-protocol/src/java/server/config/client_information.rs @@ -8,7 +8,7 @@ use crate::VarInt; #[derive(serde::Deserialize, Serialize)] #[java_packet(CONFIG_CLIENT_INFORMATION)] pub struct SClientInformationConfig { - /// The language code used by the client (e.g., "en_us") + /// The language code used by the client (e.g., "`en_us`") pub locale: String, /// The maximum number of chunks the client renders pub view_distance: i8, diff --git a/pumpkin-protocol/src/java/server/config/plugin_message.rs b/pumpkin-protocol/src/java/server/config/plugin_message.rs index 291a6e6c6..15f76020c 100644 --- a/pumpkin-protocol/src/java/server/config/plugin_message.rs +++ b/pumpkin-protocol/src/java/server/config/plugin_message.rs @@ -7,7 +7,7 @@ use pumpkin_util::resource_location::ResourceLocation; use crate::{ReadingError, ServerPacket, ser::NetworkReadExt}; /// The maximum allowed size for a plugin message payload (1 MiB). -const MAX_PAYLOAD_SIZE: usize = 1048576; +const MAX_PAYLOAD_SIZE: usize = 1_048_576; /// A packet used for custom communication between the client and server. /// diff --git a/pumpkin-protocol/src/java/server/config/resource_pack_response.rs b/pumpkin-protocol/src/java/server/config/resource_pack_response.rs index 5e46f871b..d9f846b41 100644 --- a/pumpkin-protocol/src/java/server/config/resource_pack_response.rs +++ b/pumpkin-protocol/src/java/server/config/resource_pack_response.rs @@ -26,11 +26,12 @@ pub struct SConfigResourcePack { /// The unique identifier of the resource pack this response refers to. #[serde(with = "uuid::serde::compact")] pub uuid: uuid::Uuid, - /// The status code of the operation, mapped to [ResourcePackResponseResult]. + /// The status code of the operation, mapped to [`ResourcePackResponseResult`]. result: VarInt, } impl SConfigResourcePack { + #[must_use] pub fn response_result(&self) -> ResourcePackResponseResult { match self.result.0 { 0 => ResourcePackResponseResult::DownloadSuccess, diff --git a/pumpkin-protocol/src/java/server/login/plugin_response.rs b/pumpkin-protocol/src/java/server/login/plugin_response.rs index 0043f663c..166cd032e 100644 --- a/pumpkin-protocol/src/java/server/login/plugin_response.rs +++ b/pumpkin-protocol/src/java/server/login/plugin_response.rs @@ -4,7 +4,7 @@ use crate::{ReadingError, ServerPacket, VarInt, ser::NetworkReadExt}; use pumpkin_data::packet::serverbound::LOGIN_CUSTOM_QUERY_ANSWER; use pumpkin_macros::java_packet; -const MAX_PAYLOAD_SIZE: usize = 1048576; +const MAX_PAYLOAD_SIZE: usize = 1_048_576; #[java_packet(LOGIN_CUSTOM_QUERY_ANSWER)] pub struct SLoginPluginResponse { diff --git a/pumpkin-protocol/src/java/server/play/custom_payload.rs b/pumpkin-protocol/src/java/server/play/custom_payload.rs index 3cf57d2c2..97bdd57c2 100644 --- a/pumpkin-protocol/src/java/server/play/custom_payload.rs +++ b/pumpkin-protocol/src/java/server/play/custom_payload.rs @@ -1,7 +1,6 @@ use pumpkin_data::packet::serverbound::PLAY_CUSTOM_PAYLOAD; use pumpkin_macros::java_packet; +// TODO #[java_packet(PLAY_CUSTOM_PAYLOAD)] -pub struct SCustomPayload { - // TODO -} +pub struct SCustomPayload; diff --git a/pumpkin-protocol/src/java/server/play/interact.rs b/pumpkin-protocol/src/java/server/play/interact.rs index c870f567f..09b62580c 100644 --- a/pumpkin-protocol/src/java/server/play/interact.rs +++ b/pumpkin-protocol/src/java/server/play/interact.rs @@ -29,8 +29,7 @@ impl ServerPacket for SInteract { let action = ActionType::try_from(r#type.0) .map_err(|_| ReadingError::Message("invalid action type".to_string()))?; let target_position: Option> = match action { - ActionType::Interact => None, - ActionType::Attack => None, + ActionType::Interact | ActionType::Attack => None, ActionType::InteractAt => Some(Vector3::new( read.get_f32_be()?, read.get_f32_be()?, @@ -38,9 +37,8 @@ impl ServerPacket for SInteract { )), }; let hand = match action { - ActionType::Interact => Some(read.get_var_int()?), + ActionType::Interact | ActionType::InteractAt => Some(read.get_var_int()?), ActionType::Attack => None, - ActionType::InteractAt => Some(read.get_var_int()?), }; Ok(Self { diff --git a/pumpkin-protocol/src/java/server/play/player_action.rs b/pumpkin-protocol/src/java/server/play/player_action.rs index 17c871678..799342b9a 100644 --- a/pumpkin-protocol/src/java/server/play/player_action.rs +++ b/pumpkin-protocol/src/java/server/play/player_action.rs @@ -13,6 +13,7 @@ pub struct SPlayerAction { pub sequence: VarInt, } +#[expect(clippy::doc_markdown)] pub enum Status { /// Sent when the player starts digging a block. If the block was insta-mined or the player is in creative mode, the client will not send `Status` = `FinishedDigging``, and will assume the server completed the destruction. To detect this, it is necessary to calculate the block destruction speed server-side. StartedDigging = 0, diff --git a/pumpkin-protocol/src/java/server/play/player_position.rs b/pumpkin-protocol/src/java/server/play/player_position.rs index 3dd90b67f..f4e4a9028 100644 --- a/pumpkin-protocol/src/java/server/play/player_position.rs +++ b/pumpkin-protocol/src/java/server/play/player_position.rs @@ -6,6 +6,6 @@ use pumpkin_util::math::vector3::Vector3; #[java_packet(PLAY_MOVE_PLAYER_POS)] pub struct SPlayerPosition { pub position: Vector3, - /// bit 0: [FLAG_ON_GROUND], bit 1: [FLAG_IN_WALL] + /// bit 0: [`FLAG_ON_GROUND`], bit 1: [`FLAG_IN_WALL`] pub collision: u8, } diff --git a/pumpkin-protocol/src/java/server/play/player_position_rotation.rs b/pumpkin-protocol/src/java/server/play/player_position_rotation.rs index 748f7f73f..5d4728eb8 100644 --- a/pumpkin-protocol/src/java/server/play/player_position_rotation.rs +++ b/pumpkin-protocol/src/java/server/play/player_position_rotation.rs @@ -11,6 +11,6 @@ pub struct SPlayerPositionRotation { pub position: Vector3, pub yaw: f32, pub pitch: f32, - /// bit 0: [FLAG_ON_GROUND], bit 1: [FLAG_IN_WALL] + /// bit 0: [`FLAG_ON_GROUND`], bit 1: [`FLAG_IN_WALL`] pub collision: u8, } diff --git a/pumpkin-protocol/src/lib.rs b/pumpkin-protocol/src/lib.rs index c352723b5..63226daa4 100644 --- a/pumpkin-protocol/src/lib.rs +++ b/pumpkin-protocol/src/lib.rs @@ -32,8 +32,8 @@ pub mod query; pub mod ser; pub mod serial; -pub const MAX_PACKET_SIZE: u64 = 2097152; -pub const MAX_PACKET_DATA_SIZE: usize = 8388608; +pub const MAX_PACKET_SIZE: u64 = 2_097_152; +pub const MAX_PACKET_DATA_SIZE: usize = 8_388_608; pub type FixedBitSet = Box<[u8]>; @@ -158,8 +158,8 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for IdOr { impl Serialize for IdOr { fn serialize(&self, serializer: S) -> Result { match self { - IdOr::Id(id) => VarInt::from(*id + 1).serialize(serializer), - IdOr::Value(value) => { + Self::Id(id) => VarInt::from(*id + 1).serialize(serializer), + Self::Value(value) => { #[derive(Serialize)] struct NetworkRepr { zero_id: VarInt, @@ -212,7 +212,7 @@ impl AsyncRead for StreamDecryptor { // Read the raw data let internal_poll = read.poll_read(cx, buf); - if matches!(internal_poll, Poll::Ready(Ok(_))) { + if matches!(internal_poll, Poll::Ready(Ok(()))) { // Decrypt the raw data in-place, note that our block size is 1 byte, so this is always safe for block in buf.filled_mut()[original_fill..].chunks_mut(Aes128Cfb8Dec::block_size()) { cipher.decrypt_block_mut(block.into()); @@ -275,10 +275,9 @@ impl AsyncWrite for StreamEncryptor { if total_written == 0 { //If we didn't write anything, return pending return Poll::Pending; - } else { - // Otherwise, we actually did write something - return Poll::Ready(Ok(total_written)); } + // Otherwise, we actually did write something + return Poll::Ready(Ok(total_written)); } Poll::Ready(result) => { ref_self.last_unwritten_encrypted_byte = None; @@ -450,19 +449,20 @@ pub enum PositionFlag { impl PositionFlag { fn get_mask(&self) -> i32 { match self { - PositionFlag::X => 1 << 0, - PositionFlag::Y => 1 << 1, - PositionFlag::Z => 1 << 2, - PositionFlag::YRot => 1 << 3, - PositionFlag::XRot => 1 << 4, - PositionFlag::DeltaX => 1 << 5, - PositionFlag::DeltaY => 1 << 6, - PositionFlag::DeltaZ => 1 << 7, - PositionFlag::RotateDelta => 1 << 8, + Self::X => 1 << 0, + Self::Y => 1 << 1, + Self::Z => 1 << 2, + Self::YRot => 1 << 3, + Self::XRot => 1 << 4, + Self::DeltaX => 1 << 5, + Self::DeltaY => 1 << 6, + Self::DeltaZ => 1 << 7, + Self::RotateDelta => 1 << 8, } } - pub fn get_bitfield(flags: &[PositionFlag]) -> i32 { + #[must_use] + pub fn get_bitfield(flags: &[Self]) -> i32 { flags.iter().fold(0, |acc, flag| acc | flag.get_mask()) } } @@ -475,8 +475,8 @@ pub enum Label { impl Serialize for Label { fn serialize(&self, serializer: S) -> Result { match self { - Label::BuiltIn(link_type) => link_type.serialize(serializer), - Label::TextComponent(component) => component.serialize(serializer), + Self::BuiltIn(link_type) => link_type.serialize(serializer), + Self::TextComponent(component) => component.serialize(serializer), } } } @@ -489,6 +489,7 @@ pub struct Link<'a> { } impl<'a> Link<'a> { + #[must_use] pub fn new(label: Label, url: &'a String) -> Self { Self { is_built_in: match label { diff --git a/pumpkin-protocol/src/query.rs b/pumpkin-protocol/src/query.rs index ef1f5357b..df4bbf02e 100644 --- a/pumpkin-protocol/src/query.rs +++ b/pumpkin-protocol/src/query.rs @@ -2,6 +2,14 @@ use std::{ffi::CString, io::Cursor}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; +const PADDING_START: [u8; 11] = [ + 0x73, 0x70, 0x6C, 0x69, 0x74, 0x6E, 0x75, 0x6D, 0x00, 0x80, 0x00, +]; + +const PADDING_END: [u8; 11] = [ + 0x00, 0x01, 0x70, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x5F, 0x00, 0x00, +]; + pub enum PacketType { // There could be other types, but they are not documented. // Besides, these types are enough to get the server status. @@ -188,9 +196,6 @@ impl CFullStatus { // Padding (11 bytes, meaningless) // This is the padding used by vanilla. // Although meaningless, it seems in testing some query checkers depend on these bytes? - const PADDING_START: [u8; 11] = [ - 0x73, 0x70, 0x6C, 0x69, 0x74, 0x6E, 0x75, 0x6D, 0x00, 0x80, 0x00, - ]; buf.extend_from_slice(PADDING_START.as_slice()); // Key-value pairs @@ -221,9 +226,7 @@ impl CFullStatus { } // Padding (10 bytes, meaningless), with one extra 0x00 for the extra required null terminator after the key-value section - const PADDING_END: [u8; 11] = [ - 0x00, 0x01, 0x70, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x5F, 0x00, 0x00, - ]; + buf.extend_from_slice(PADDING_END.as_slice()); // Players @@ -261,7 +264,7 @@ async fn test_handshake_response() { challenge_token: 9513307, }; - assert_eq!(bytes, packet.encode().await) + assert_eq!(bytes, packet.encode().await); } #[tokio::test] diff --git a/pumpkin-protocol/src/ser/deserializer.rs b/pumpkin-protocol/src/ser/deserializer.rs index a3e7ad3e9..413c665f4 100644 --- a/pumpkin-protocol/src/ser/deserializer.rs +++ b/pumpkin-protocol/src/ser/deserializer.rs @@ -85,12 +85,14 @@ impl<'de, R: Read> de::Deserializer<'de> for &mut Deserializer { fn deserialize_char>(self, visitor: V) -> Result { let u32_val = self.inner.get_u32_be()?; - match char::from_u32(u32_val) { - Some(c) => visitor.visit_char(c), - None => Err(ReadingError::Message(format!( - "Invalid char value: {u32_val}" - ))), - } + char::from_u32(u32_val).map_or_else( + || { + Err(ReadingError::Message(format!( + "Invalid char value: {u32_val}" + ))) + }, + |c| visitor.visit_char(c), + ) } fn deserialize_str>(self, visitor: V) -> Result { @@ -200,12 +202,10 @@ impl<'de, R: Read> de::Deserializer<'de> for &mut Deserializer { } fn deserialize_map>(self, visitor: V) -> Result { - let len = self.inner.get_var_int()?.0 as usize; struct Access<'a, R: Read> { deserializer: &'a mut Deserializer, len: usize, } - impl<'de, R: Read> MapAccess<'de> for Access<'_, R> { type Error = ReadingError; @@ -227,6 +227,7 @@ impl<'de, R: Read> de::Deserializer<'de> for &mut Deserializer { seed.deserialize(&mut *self.deserializer) } } + let len = self.inner.get_var_int()?.0 as usize; visitor.visit_map(Access { deserializer: self, @@ -272,10 +273,10 @@ impl<'de, R: Read> EnumAccess<'de> for &mut Deserializer { self, seed: V, ) -> Result<(V::Value, Self::Variant), Self::Error> { - let variant_index_i32 = self.inner.get_var_int()?.0; - let variant_index_u32: u32 = variant_index_i32.try_into().map_err(|_| { + let variant_index = self.inner.get_var_int()?.0; + let variant_index_u32: u32 = variant_index.try_into().map_err(|_| { ReadingError::Message(format!( - "Invalid variant index {variant_index_i32} for enum, cannot convert to u32" + "Invalid variant index {variant_index} for enum, cannot convert to u32" )) })?; let val = seed.deserialize(variant_index_u32.into_deserializer())?; diff --git a/pumpkin-protocol/src/ser/mod.rs b/pumpkin-protocol/src/ser/mod.rs index 578425a18..2c4d73c89 100644 --- a/pumpkin-protocol/src/ser/mod.rs +++ b/pumpkin-protocol/src/ser/mod.rs @@ -173,7 +173,7 @@ impl NetworkReadExt for R { fn get_resource_location(&mut self) -> Result { let resource_location = self.get_string_bounded(ResourceLocation::MAX_SIZE.get())?; - match resource_location.split_once(":") { + match resource_location.split_once(':') { Some((namespace, path)) => Ok(ResourceLocation { namespace: namespace.to_string(), path: path.to_string(), @@ -560,7 +560,12 @@ mod test { fn test_unit_reserialize() { #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] struct UnitStruct; - + #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] + struct StructWithUnit { + a: i32, + b: UnitStruct, + c: i32, + } let original = UnitStruct; let mut bytes = Vec::new(); let mut ser = serializer::Serializer::new(&mut bytes); @@ -572,13 +577,6 @@ mod test { UnitStruct::deserialize(&mut deserializer::Deserializer::new(de_cursor)).unwrap(); assert_eq!(original, deserialized); - #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] - struct StructWithUnit { - a: i32, - b: UnitStruct, - c: i32, - } - let original_with_unit = StructWithUnit { a: 1, b: UnitStruct, diff --git a/pumpkin-protocol/src/ser/serializer.rs b/pumpkin-protocol/src/ser/serializer.rs index a1bb9c1d3..f611a4da2 100644 --- a/pumpkin-protocol/src/ser/serializer.rs +++ b/pumpkin-protocol/src/ser/serializer.rs @@ -45,7 +45,7 @@ impl ser::SerializeSeq for NonPrefixedSeqSerializer<'_, W> { type Error = WritingError; fn serialize_element(&mut self, value: &T) -> Result<(), Self::Error> { - value.serialize(&mut *self.wrapped).map(|_| ()) + value.serialize(&mut *self.wrapped) } fn end(self) -> Result { diff --git a/pumpkin-protocol/src/serial/deserializer.rs b/pumpkin-protocol/src/serial/deserializer.rs index bf9ec8547..62edeee5a 100644 --- a/pumpkin-protocol/src/serial/deserializer.rs +++ b/pumpkin-protocol/src/serial/deserializer.rs @@ -134,7 +134,7 @@ impl PacketRead for [T; N] { impl PacketRead for String { fn read(reader: &mut R) -> Result { let vec = Vec::read(reader)?; - Ok(unsafe { String::from_utf8_unchecked(vec) }) + Ok(unsafe { Self::from_utf8_unchecked(vec) }) } } @@ -143,10 +143,10 @@ impl PacketRead for Vec { #[expect(clippy::uninit_vec)] { let len = VarUInt::read(reader)?.0 as _; - let mut buf = Vec::with_capacity(len); + let mut buf = Self::with_capacity(len); unsafe { buf.set_len(len); - } + }; reader.read_exact(&mut buf)?; Ok(buf) } @@ -178,7 +178,7 @@ impl PacketRead for SocketAddr { 4 => { let ip = u32::read_be(reader)?; let port = u16::read_be(reader)?; - Ok(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::from(ip), port))) + Ok(Self::V4(SocketAddrV4::new(Ipv4Addr::from(ip), port))) } 6 => { // Addr family @@ -192,9 +192,7 @@ impl PacketRead for SocketAddr { let scope_id = u32::read_be(reader)?; - Ok(SocketAddr::V6(SocketAddrV6::new( - ip, port, flowinfo, scope_id, - ))) + Ok(Self::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id))) } _ => Err(Error::other("Invalid socket address version")), } @@ -205,7 +203,7 @@ impl PacketRead for Uuid { fn read(reader: &mut R) -> Result { let mut bytes = [0; 16]; reader.read_exact(&mut bytes)?; - Ok(Uuid::from_bytes(bytes)) + Ok(Self::from_bytes(bytes)) } } diff --git a/pumpkin-protocol/src/serial/serializer.rs b/pumpkin-protocol/src/serial/serializer.rs index c88e6becd..6b0896137 100644 --- a/pumpkin-protocol/src/serial/serializer.rs +++ b/pumpkin-protocol/src/serial/serializer.rs @@ -101,7 +101,7 @@ impl PacketWrite for f64 { impl PacketWrite for [T; N] { fn write(&self, writer: &mut W) -> Result<(), Error> { - for item in self.iter() { + for item in self { item.write(writer)?; } Ok(()) @@ -110,7 +110,7 @@ impl PacketWrite for [T; N] { impl PacketWrite for Vec { fn write(&self, writer: &mut W) -> Result<(), Error> { - for item in self.iter() { + for item in self { item.write(writer)?; } Ok(()) @@ -156,13 +156,13 @@ impl PacketWrite for SocketAddr { fn write(&self, writer: &mut W) -> Result<(), Error> { match self { // version, addr, port - SocketAddr::V4(addr) => { + Self::V4(addr) => { 4u8.write(writer)?; writer.write_all(&addr.ip().octets())?; addr.port().write_be(writer) } // version, addr_family, port, flow_info, addr, scope_id - SocketAddr::V6(addr) => { + Self::V6(addr) => { 6u8.write(writer)?; 10u16.write(writer)?; addr.port().write_be(writer)?; diff --git a/pumpkin-util/Cargo.toml b/pumpkin-util/Cargo.toml index 20ac68265..ee9706d8b 100644 --- a/pumpkin-util/Cargo.toml +++ b/pumpkin-util/Cargo.toml @@ -28,3 +28,6 @@ base64.workspace = true p384 = { workspace = true, features = ["ecdsa"] } thiserror.workspace = true ecdsa.workspace = true + +[lints] +workspace = true diff --git a/pumpkin-util/src/biome.rs b/pumpkin-util/src/biome.rs index 5b318f1c0..b52571422 100644 --- a/pumpkin-util/src/biome.rs +++ b/pumpkin-util/src/biome.rs @@ -29,8 +29,8 @@ pub enum TemperatureModifier { impl TemperatureModifier { pub fn convert_temperature(&self, x: f64, z: f64, temperature: f32) -> f32 { match self { - TemperatureModifier::None => temperature, - TemperatureModifier::Frozen => { + Self::None => temperature, + Self::Frozen => { let frozen_ocean_sample = FROZEN_OCEAN_NOISE.sample(x * 0.05, z * 0.05, false) * 7.0; let foliage_sample = FOLIAGE_NOISE.sample(x * 0.2, z * 0.2, false); @@ -60,6 +60,7 @@ pub struct Weather { } impl Weather { + #[must_use] pub const fn new( has_precipitation: bool, temperature: f32, diff --git a/pumpkin-util/src/gamemode.rs b/pumpkin-util/src/gamemode.rs index f6839c5ad..bd6ba91b1 100644 --- a/pumpkin-util/src/gamemode.rs +++ b/pumpkin-util/src/gamemode.rs @@ -13,6 +13,7 @@ pub enum GameMode { } impl GameMode { + #[must_use] pub fn to_str(&self) -> &'static str { match self { Self::Survival => "Survival", diff --git a/pumpkin-util/src/lib.rs b/pumpkin-util/src/lib.rs index 7b33b8fdf..c2447f283 100644 --- a/pumpkin-util/src/lib.rs +++ b/pumpkin-util/src/lib.rs @@ -71,11 +71,12 @@ macro_rules! include_json_static { /// The minimum number of bits required to represent this number #[inline] +#[must_use] pub fn encompassing_bits(count: usize) -> u8 { if count == 1 { 1 } else { - count.ilog2() as u8 + if count.is_power_of_two() { 0 } else { 1 } + count.ilog2() as u8 + u8::from(!count.is_power_of_two()) } } @@ -97,11 +98,12 @@ pub enum BlockDirection { } impl BlockDirection { + #[must_use] pub fn get_axis(&self) -> Axis { match self { - BlockDirection::Up | BlockDirection::Down => Axis::Y, - BlockDirection::North | BlockDirection::South => Axis::Z, - BlockDirection::East | BlockDirection::West => Axis::X, + Self::Up | Self::Down => Axis::Y, + Self::North | Self::South => Axis::Z, + Self::East | Self::West => Axis::X, } } } @@ -123,10 +125,12 @@ impl<'a, T> MutableSplitSlice<'a, T> { (value, Self { start, end }) } + #[must_use] pub fn len(&self) -> usize { self.start.len() + self.end.len() + 1 } + #[must_use] pub fn is_empty(&self) -> bool { false } @@ -186,6 +190,7 @@ pub enum Hand { } impl Hand { + #[must_use] pub fn all() -> [Self; 2] { [Self::Right, Self::Left] } diff --git a/pumpkin-util/src/loot_table.rs b/pumpkin-util/src/loot_table.rs index 84913edcb..c12432146 100644 --- a/pumpkin-util/src/loot_table.rs +++ b/pumpkin-util/src/loot_table.rs @@ -141,7 +141,7 @@ pub enum LootNumberProviderTypesProvider { impl ToTokens for LootNumberProviderTypesProvider { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - LootNumberProviderTypesProvider::Uniform(uniform) => { + Self::Uniform(uniform) => { tokens.extend(quote! { LootNumberProviderTypesProvider::Uniform(#uniform) }); @@ -183,12 +183,12 @@ pub enum LootNumberProviderTypes { impl ToTokens for LootNumberProviderTypes { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - LootNumberProviderTypes::Object(provider) => { + Self::Object(provider) => { tokens.extend(quote! { LootNumberProviderTypes::Object(#provider) }); } - LootNumberProviderTypes::Constant(i) => tokens.extend(quote! { + Self::Constant(i) => tokens.extend(quote! { LootNumberProviderTypes::Constant(#i) }), } @@ -198,10 +198,10 @@ impl ToTokens for LootNumberProviderTypes { impl LootNumberProviderTypes { pub fn get(&self, random: &mut impl RandomImpl) -> f32 { match self { - LootNumberProviderTypes::Object(int_provider) => match int_provider { + Self::Object(int_provider) => match int_provider { LootNumberProviderTypesProvider::Uniform(uniform) => uniform.get(random), }, - LootNumberProviderTypes::Constant(i) => *i, + Self::Constant(i) => *i, } } } diff --git a/pumpkin-util/src/math/block_box.rs b/pumpkin-util/src/math/block_box.rs index 562ba7a4c..5cf80d2e4 100644 --- a/pumpkin-util/src/math/block_box.rs +++ b/pumpkin-util/src/math/block_box.rs @@ -13,8 +13,9 @@ pub struct BlockBox { } impl BlockBox { + #[must_use] pub fn new(min_x: i32, min_y: i32, min_z: i32, max_x: i32, max_y: i32, max_z: i32) -> Self { - BlockBox { + Self { min: Vector3 { x: min_x, y: min_y, @@ -27,6 +28,7 @@ impl BlockBox { }, } } + #[must_use] pub fn create_box( x: i32, y: i32, @@ -44,6 +46,7 @@ impl BlockBox { } #[expect(clippy::too_many_arguments)] + #[must_use] pub fn rotated( x: i32, y: i32, @@ -57,7 +60,7 @@ impl BlockBox { facing: &BlockDirection, ) -> Self { match facing { - BlockDirection::North => BlockBox::new( + BlockDirection::North => Self::new( x + offset_x, y + offset_y, z - size_z + 1 + offset_z, @@ -65,7 +68,7 @@ impl BlockBox { y + size_y - 1 + offset_y, z + offset_z, ), - BlockDirection::West => BlockBox::new( + BlockDirection::West => Self::new( x - size_z + 1 + offset_z, y + offset_y, z + offset_x, @@ -73,7 +76,7 @@ impl BlockBox { y + size_y - 1 + offset_y, z + size_x - 1 + offset_x, ), - BlockDirection::East => BlockBox::new( + BlockDirection::East => Self::new( x + offset_z, y + offset_y, z + offset_x, @@ -82,7 +85,7 @@ impl BlockBox { z + size_x - 1 + offset_x, ), // Default / South - _ => BlockBox::new( + _ => Self::new( x + offset_x, y + offset_y, z + offset_z, @@ -93,6 +96,7 @@ impl BlockBox { } } + #[must_use] pub fn from_pos(pos: BlockPos) -> Self { Self { min: pos.0, @@ -100,6 +104,7 @@ impl BlockBox { } } + #[must_use] pub fn expand(&self, x: i32, y: i32, z: i32) -> Self { Self { min: Vector3::new(self.min.x - x, self.min.y - y, self.min.z - z), @@ -116,10 +121,12 @@ impl BlockBox { self.max.z += dz; } + #[must_use] pub fn contains_pos(&self, pos: &Vector3) -> bool { self.contains(pos.x, pos.y, pos.z) } + #[must_use] pub fn contains(&self, x: i32, y: i32, z: i32) -> bool { x >= self.min.x && x <= self.max.x @@ -129,6 +136,7 @@ impl BlockBox { && z <= self.max.z } + #[must_use] pub fn intersects(&self, other: &Self) -> bool { self.min.x < other.max.x && self.max.x > other.min.x @@ -136,6 +144,7 @@ impl BlockBox { && self.max.y > other.min.y } + #[must_use] pub fn intersects_xz(&self, other: &Self) -> bool { self.max.x >= other.min.x && self.min.x <= other.max.x @@ -143,15 +152,17 @@ impl BlockBox { && self.min.z <= other.max.z } + #[must_use] pub fn intersects_raw_xz(&self, min_x: i32, min_z: i32, max_x: i32, max_z: i32) -> bool { self.max.x >= min_x && self.min.x <= max_x && self.max.z >= min_z && self.min.z <= max_z } + #[must_use] pub fn get_block_count_y(&self) -> i32 { self.max.y - self.min.y + 1 } - pub fn encompass(&mut self, other: &BlockBox) { + pub fn encompass(&mut self, other: &Self) { self.min.x = self.min.x.min(other.min.x); self.min.y = self.min.y.min(other.min.y); self.min.z = self.min.z.min(other.min.z); @@ -161,9 +172,9 @@ impl BlockBox { } /// Static helper to find the box covering a collection of boxes - pub fn encompass_all(boxes: I) -> Option + pub fn encompass_all(boxes: I) -> Option where - I: IntoIterator, + I: IntoIterator, { let mut iter = boxes.into_iter(); let mut result = iter.next()?; // Return None if empty diff --git a/pumpkin-util/src/math/boundingbox.rs b/pumpkin-util/src/math/boundingbox.rs index 9c65feb32..a68eae85a 100644 --- a/pumpkin-util/src/math/boundingbox.rs +++ b/pumpkin-util/src/math/boundingbox.rs @@ -42,18 +42,21 @@ impl BoundingPlane { } impl BoundingBox { + #[must_use] pub fn new_default(size: &EntityDimensions) -> Self { Self::new_from_pos(0., 0., 0., size) } + #[must_use] pub fn new_from_pos(x: f64, y: f64, z: f64, size: &EntityDimensions) -> Self { - let f = size.width as f64 / 2.; + let f = f64::from(size.width) / 2.; Self { min: Vector3::new(x - f, y, z - f), - max: Vector3::new(x + f, y + size.height as f64, z + f), + max: Vector3::new(x + f, y + f64::from(size.height), z + f), } } + #[must_use] pub fn expand(&self, x: f64, y: f64, z: f64) -> Self { Self { min: Vector3::new(self.min.x - x, self.min.y - y, self.min.z - z), @@ -61,14 +64,17 @@ impl BoundingBox { } } + #[must_use] pub fn expand_all(&self, value: f64) -> Self { self.expand(value, value, value) } + #[must_use] pub fn contract_all(&self, value: f64) -> Self { self.expand_all(-value) } + #[must_use] pub fn offset(&self, other: Self) -> Self { Self { min: self.min.add(&other.min), @@ -76,10 +82,12 @@ impl BoundingBox { } } + #[must_use] pub fn new(min: Vector3, max: Vector3) -> Self { Self { min, max } } + #[must_use] pub fn new_array(min: [f64; 3], max: [f64; 3]) -> Self { Self { min: Vector3::new(min[0], min[1], min[2]), @@ -87,22 +95,29 @@ impl BoundingBox { } } + #[must_use] pub fn from_block(position: &BlockPos) -> Self { let position = position.0; Self { - min: Vector3::new(position.x as f64, position.y as f64, position.z as f64), + min: Vector3::new( + f64::from(position.x), + f64::from(position.y), + f64::from(position.z), + ), max: Vector3::new( - position.x as f64 + 1.0, - position.y as f64 + 1.0, - position.z as f64 + 1.0, + f64::from(position.x) + 1.0, + f64::from(position.y) + 1.0, + f64::from(position.z) + 1.0, ), } } + #[must_use] pub fn get_side(&self, max: bool) -> Vector3 { if max { self.max } else { self.min } } + #[must_use] pub fn calculate_collision_time( &self, other: &Self, @@ -138,6 +153,7 @@ impl BoundingBox { Some(collision_time) } + #[must_use] pub fn get_average_side_length(&self) -> f64 { let width = self.max.x - self.min.x; let height = self.max.y - self.min.y; @@ -146,14 +162,17 @@ impl BoundingBox { (width + height + depth) / 3.0 } + #[must_use] pub fn min_block_pos(&self) -> BlockPos { BlockPos::floored_v(self.min) } + #[must_use] pub fn max_block_pos(&self) -> BlockPos { BlockPos::ceiled_v(self.max) } + #[must_use] pub fn shift(&self, delta: Vector3) -> Self { Self { min: self.min + delta, @@ -162,6 +181,7 @@ impl BoundingBox { } } + #[must_use] pub fn stretch(&self, other: Vector3) -> Self { let mut new = *self; @@ -186,15 +206,25 @@ impl BoundingBox { new } + #[must_use] pub fn from_block_raw(position: &BlockPos) -> Self { let position = position.0; Self { - min: Vector3::new(position.x as f64, position.y as f64, position.z as f64), - max: Vector3::new(position.x as f64, position.y as f64, position.z as f64), + min: Vector3::new( + f64::from(position.x), + f64::from(position.y), + f64::from(position.z), + ), + max: Vector3::new( + f64::from(position.x), + f64::from(position.y), + f64::from(position.z), + ), } } - pub fn intersects(&self, other: &BoundingBox) -> bool { + #[must_use] + pub fn intersects(&self, other: &Self) -> bool { self.min.x < other.max.x && self.max.x > other.min.x && self.min.y < other.max.y @@ -203,6 +233,7 @@ impl BoundingBox { && self.max.z > other.min.z } + #[must_use] pub fn squared_magnitude(&self, pos: Vector3) -> f64 { let d = f64::max(f64::max(self.min.x - pos.x, pos.x - self.max.x), 0.0); let e = f64::max(f64::max(self.min.y - pos.y, pos.y - self.max.y), 0.0); @@ -219,6 +250,7 @@ pub struct EntityDimensions { } impl EntityDimensions { + #[must_use] pub fn new(width: f32, height: f32, eye_height: f32) -> Self { Self { width, diff --git a/pumpkin-util/src/math/euler_angle.rs b/pumpkin-util/src/math/euler_angle.rs index f8b9f0be2..158256184 100644 --- a/pumpkin-util/src/math/euler_angle.rs +++ b/pumpkin-util/src/math/euler_angle.rs @@ -9,6 +9,7 @@ pub struct EulerAngle { } impl EulerAngle { + #[must_use] pub fn new(pitch: f32, yaw: f32, roll: f32) -> Self { let pitch = pitch % 360.0; let yaw = yaw % 360.0; @@ -17,7 +18,7 @@ impl EulerAngle { Self { pitch, yaw, roll } } - pub const ZERO: EulerAngle = EulerAngle { + pub const ZERO: Self = Self { pitch: 0.0, yaw: 0.0, roll: 0.0, @@ -32,10 +33,10 @@ impl Default for EulerAngle { impl From for NbtTag { fn from(val: EulerAngle) -> Self { - NbtTag::List(vec![ - NbtTag::Float(val.pitch), - NbtTag::Float(val.yaw), - NbtTag::Float(val.roll), + Self::List(vec![ + Self::Float(val.pitch), + Self::Float(val.yaw), + Self::Float(val.roll), ]) } } diff --git a/pumpkin-util/src/math/experience.rs b/pumpkin-util/src/math/experience.rs index 3ef6d37f5..9e4124a4e 100644 --- a/pumpkin-util/src/math/experience.rs +++ b/pumpkin-util/src/math/experience.rs @@ -20,6 +20,7 @@ impl ToTokens for Experience { } /// Get the number of points in a level. +#[must_use] pub fn points_in_level(level: i32) -> i32 { match level { 0..=15 => 2 * level + 7, @@ -29,6 +30,7 @@ pub fn points_in_level(level: i32) -> i32 { } /// Calculate the total number of points to reach a level. +#[must_use] pub fn points_to_level(level: i32) -> i32 { match level { 0..=16 => level * level + 6 * level, @@ -38,12 +40,14 @@ pub fn points_to_level(level: i32) -> i32 { } /// Calculate level and points from total points. +#[must_use] pub fn total_to_level_and_points(total_points: i32) -> (i32, i32) { let level = match total_points { - 0..=352 => ((total_points as f64 + 9.0).sqrt() - 3.0) as i32, - 353..=1507 => (8.1 + (0.4 * (total_points as f64 - (7839.0 / 40.0))).sqrt()) as i32, + 0..=352 => ((f64::from(total_points) + 9.0).sqrt() - 3.0) as i32, + 353..=1507 => (8.1 + (0.4 * (f64::from(total_points) - (7839.0 / 40.0))).sqrt()) as i32, _ => { - ((325.0 / 18.0) + (2.0 / 9.0 * (total_points as f64 - (54215.0 / 72.0))).sqrt()) as i32 + ((325.0 / 18.0) + (2.0 / 9.0 * (f64::from(total_points) - (54215.0 / 72.0))).sqrt()) + as i32 } }; @@ -54,6 +58,7 @@ pub fn total_to_level_and_points(total_points: i32) -> (i32, i32) { } /// Calculate progress (0.0 to 1.0) from points within a level. +#[must_use] pub fn progress_in_level(points: i32, level: i32) -> f32 { let max_points = points_in_level(level); diff --git a/pumpkin-util/src/math/float_provider.rs b/pumpkin-util/src/math/float_provider.rs index 1f9085b38..c02a85df5 100644 --- a/pumpkin-util/src/math/float_provider.rs +++ b/pumpkin-util/src/math/float_provider.rs @@ -20,22 +20,22 @@ pub enum NormalFloatProvider { impl ToTokens for NormalFloatProvider { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - NormalFloatProvider::Constant(constant) => { + Self::Constant(constant) => { tokens.extend(quote! { NormalFloatProvider::Constant(#constant) }); } - NormalFloatProvider::Uniform(uniform) => { + Self::Uniform(uniform) => { tokens.extend(quote! { NormalFloatProvider::Uniform(#uniform) }); } - NormalFloatProvider::ClampedNormal(clamped_normal) => { + Self::ClampedNormal(clamped_normal) => { tokens.extend(quote! { NormalFloatProvider::ClampedNormal(#clamped_normal) }); } - NormalFloatProvider::Trapezoid(trapezoid) => { + Self::Trapezoid(trapezoid) => { tokens.extend(quote! { NormalFloatProvider::Trapezoid(#trapezoid) }); @@ -54,12 +54,12 @@ pub enum FloatProvider { impl ToTokens for FloatProvider { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - FloatProvider::Object(float_provider) => { + Self::Object(float_provider) => { tokens.extend(quote! { FloatProvider::Object(#float_provider) }); } - FloatProvider::Constant(f) => tokens.extend(quote! { + Self::Constant(f) => tokens.extend(quote! { FloatProvider::Constant(#f) }), } @@ -67,39 +67,41 @@ impl ToTokens for FloatProvider { } impl FloatProvider { + #[must_use] pub fn get_min(&self) -> f32 { match self { - FloatProvider::Object(inv_provider) => match inv_provider { + Self::Object(inv_provider) => match inv_provider { NormalFloatProvider::Constant(constant) => constant.get_min(), NormalFloatProvider::Uniform(uniform) => uniform.get_min(), NormalFloatProvider::ClampedNormal(clamped_normal) => clamped_normal.get_min(), NormalFloatProvider::Trapezoid(trapezoid) => trapezoid.get_min(), }, - FloatProvider::Constant(i) => *i, + Self::Constant(i) => *i, } } pub fn get(&self, random: &mut impl RandomImpl) -> f32 { match self { - FloatProvider::Object(inv_provider) => match inv_provider { + Self::Object(inv_provider) => match inv_provider { NormalFloatProvider::Constant(constant) => constant.get(random), NormalFloatProvider::Uniform(uniform) => uniform.get(random), NormalFloatProvider::ClampedNormal(clamped_normal) => clamped_normal.get(random), NormalFloatProvider::Trapezoid(trapezoid) => trapezoid.get(random), }, - FloatProvider::Constant(i) => *i, + Self::Constant(i) => *i, } } + #[must_use] pub fn get_max(&self) -> f32 { match self { - FloatProvider::Object(inv_provider) => match inv_provider { + Self::Object(inv_provider) => match inv_provider { NormalFloatProvider::Constant(constant) => constant.get_max(), NormalFloatProvider::Uniform(uniform) => uniform.get_max(), NormalFloatProvider::ClampedNormal(clamped_normal) => clamped_normal.get_max(), NormalFloatProvider::Trapezoid(trapezoid) => trapezoid.get_max(), }, - FloatProvider::Constant(i) => *i, + Self::Constant(i) => *i, } } } @@ -119,10 +121,12 @@ impl ToTokens for ConstantFloatProvider { } impl ConstantFloatProvider { + #[must_use] pub fn new(value: f32) -> Self { Self { value } } + #[must_use] pub fn get_min(&self) -> f32 { self.value } @@ -131,6 +135,7 @@ impl ConstantFloatProvider { self.value } + #[must_use] pub fn get_max(&self) -> f32 { self.value } @@ -153,6 +158,7 @@ impl ToTokens for UniformFloatProvider { } impl UniformFloatProvider { + #[must_use] pub fn new(min_inclusive: f32, max_exclusive: f32) -> Self { Self { min_inclusive, @@ -160,6 +166,7 @@ impl UniformFloatProvider { } } + #[must_use] pub fn get_min(&self) -> f32 { self.min_inclusive } @@ -170,6 +177,7 @@ impl UniformFloatProvider { self.min_inclusive + random.next_f32() * range } + #[must_use] pub fn get_max(&self) -> f32 { self.max_exclusive } @@ -201,6 +209,7 @@ impl ToTokens for ClampedNormalFloatProvider { } impl ClampedNormalFloatProvider { + #[must_use] pub fn new(mean: f32, deviation: f32, min: f32, max: f32) -> Self { Self { mean, @@ -210,6 +219,7 @@ impl ClampedNormalFloatProvider { } } + #[must_use] pub fn get_min(&self) -> f32 { self.min } @@ -223,6 +233,7 @@ impl ClampedNormalFloatProvider { value.clamp(self.min, self.max) } + #[must_use] pub fn get_max(&self) -> f32 { self.max } @@ -251,10 +262,12 @@ impl ToTokens for TrapezoidFloatProvider { } impl TrapezoidFloatProvider { + #[must_use] pub fn new(min: f32, max: f32, plateau: f32) -> Self { Self { min, max, plateau } } + #[must_use] pub fn get_min(&self) -> f32 { self.min } @@ -284,6 +297,7 @@ impl TrapezoidFloatProvider { } } + #[must_use] pub fn get_max(&self) -> f32 { self.max } diff --git a/pumpkin-util/src/math/int_provider.rs b/pumpkin-util/src/math/int_provider.rs index b40bb607c..76ae95a30 100644 --- a/pumpkin-util/src/math/int_provider.rs +++ b/pumpkin-util/src/math/int_provider.rs @@ -24,32 +24,32 @@ pub enum NormalIntProvider { impl ToTokens for NormalIntProvider { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - NormalIntProvider::Constant(constant) => { + Self::Constant(constant) => { tokens.extend(quote! { NormalIntProvider::Constant(#constant) }); } - NormalIntProvider::Uniform(uniform) => { + Self::Uniform(uniform) => { tokens.extend(quote! { NormalIntProvider::Uniform(#uniform) }); } - NormalIntProvider::BiasedToBottom(biased) => { + Self::BiasedToBottom(biased) => { tokens.extend(quote! { NormalIntProvider::BiasedToBottom(#biased) }); } - NormalIntProvider::Clamped(clamped) => { + Self::Clamped(clamped) => { tokens.extend(quote! { NormalIntProvider::Clamped(#clamped) }); } - NormalIntProvider::ClampedNormal(clamped_normal) => { + Self::ClampedNormal(clamped_normal) => { tokens.extend(quote! { NormalIntProvider::ClampedNormal(#clamped_normal) }); } - NormalIntProvider::WeightedList(weighted_list) => { + Self::WeightedList(weighted_list) => { tokens.extend(quote! { NormalIntProvider::WeightedList(#weighted_list) }); @@ -68,12 +68,12 @@ pub enum IntProvider { impl ToTokens for IntProvider { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - IntProvider::Object(int_provider) => { + Self::Object(int_provider) => { tokens.extend(quote! { IntProvider::Object(#int_provider) }); } - IntProvider::Constant(i) => tokens.extend(quote! { + Self::Constant(i) => tokens.extend(quote! { IntProvider::Constant(#i) }), } @@ -81,9 +81,10 @@ impl ToTokens for IntProvider { } impl IntProvider { + #[must_use] pub fn get_min(&self) -> i32 { match self { - IntProvider::Object(int_provider) => match int_provider { + Self::Object(int_provider) => match int_provider { NormalIntProvider::Constant(constant) => constant.get_min(), NormalIntProvider::Uniform(uniform) => uniform.get_min(), NormalIntProvider::BiasedToBottom(biased) => biased.get_min(), @@ -91,13 +92,13 @@ impl IntProvider { NormalIntProvider::ClampedNormal(clamped_normal) => clamped_normal.get_min(), NormalIntProvider::WeightedList(weighted_list) => weighted_list.get_min(), }, - IntProvider::Constant(i) => *i, + Self::Constant(i) => *i, } } pub fn get(&self, random: &mut impl RandomImpl) -> i32 { match self { - IntProvider::Object(int_provider) => match int_provider { + Self::Object(int_provider) => match int_provider { NormalIntProvider::Constant(constant) => constant.get(random), NormalIntProvider::Uniform(uniform) => uniform.get(random), NormalIntProvider::BiasedToBottom(biased) => biased.get(random), @@ -105,13 +106,14 @@ impl IntProvider { NormalIntProvider::ClampedNormal(clamped_normal) => clamped_normal.get(random), NormalIntProvider::WeightedList(weighted_list) => weighted_list.get(random), }, - IntProvider::Constant(i) => *i, + Self::Constant(i) => *i, } } + #[must_use] pub fn get_max(&self) -> i32 { match self { - IntProvider::Object(int_provider) => match int_provider { + Self::Object(int_provider) => match int_provider { NormalIntProvider::Constant(constant) => constant.get_max(), NormalIntProvider::Uniform(uniform) => uniform.get_max(), NormalIntProvider::BiasedToBottom(biased) => biased.get_max(), @@ -119,7 +121,7 @@ impl IntProvider { NormalIntProvider::ClampedNormal(clamped_normal) => clamped_normal.get_max(), NormalIntProvider::WeightedList(weighted_list) => weighted_list.get_max(), }, - IntProvider::Constant(i) => *i, + Self::Constant(i) => *i, } } } @@ -139,10 +141,12 @@ impl ToTokens for ConstantIntProvider { } impl ConstantIntProvider { + #[must_use] pub fn new(value: i32) -> Self { Self { value } } + #[must_use] pub fn get_min(&self) -> i32 { self.value } @@ -151,6 +155,7 @@ impl ConstantIntProvider { self.value } + #[must_use] pub fn get_max(&self) -> i32 { self.value } @@ -173,6 +178,7 @@ impl ToTokens for BiasedToBottomIntProvider { } impl BiasedToBottomIntProvider { + #[must_use] pub fn new(min_inclusive: i32, max_inclusive: i32) -> Self { Self { min_inclusive, @@ -180,6 +186,7 @@ impl BiasedToBottomIntProvider { } } + #[must_use] pub fn get_min(&self) -> i32 { self.min_inclusive } @@ -187,11 +194,12 @@ impl BiasedToBottomIntProvider { pub fn get(&self, random: &mut impl RandomImpl) -> i32 { // Similar to uniform but biased toward lower values // Uses triangular distribution with mode at min - let range = (self.max_inclusive - self.min_inclusive + 1) as f64; + let range = f64::from(self.max_inclusive - self.min_inclusive + 1); let triangular = random.next_triangular(0.0, range); self.min_inclusive + (triangular.abs() as i32).min(self.max_inclusive - self.min_inclusive) } + #[must_use] pub fn get_max(&self) -> i32 { self.max_inclusive } @@ -220,6 +228,7 @@ impl ToTokens for ClampedIntProvider { } impl ClampedIntProvider { + #[must_use] pub fn new(source: IntProvider, min_inclusive: i32, max_inclusive: i32) -> Self { Self { source: Box::new(source), @@ -228,6 +237,7 @@ impl ClampedIntProvider { } } + #[must_use] pub fn get_min(&self) -> i32 { self.min_inclusive.max(self.source.get_min()) } @@ -238,6 +248,7 @@ impl ClampedIntProvider { .clamp(self.min_inclusive, self.max_inclusive) } + #[must_use] pub fn get_max(&self) -> i32 { self.max_inclusive.min(self.source.get_max()) } @@ -269,6 +280,7 @@ impl ToTokens for ClampedNormalIntProvider { } impl ClampedNormalIntProvider { + #[must_use] pub fn new(mean: f32, deviation: f32, min_inclusive: i32, max_inclusive: i32) -> Self { Self { mean, @@ -278,6 +290,7 @@ impl ClampedNormalIntProvider { } } + #[must_use] pub fn get_min(&self) -> i32 { self.min_inclusive } @@ -289,6 +302,7 @@ impl ClampedNormalIntProvider { value.clamp(self.min_inclusive, self.max_inclusive) } + #[must_use] pub fn get_max(&self) -> i32 { self.max_inclusive } @@ -325,10 +339,12 @@ impl ToTokens for WeightedListIntProvider { } impl WeightedListIntProvider { + #[must_use] pub fn new(distribution: Vec) -> Self { Self { distribution } } + #[must_use] pub fn get_min(&self) -> i32 { self.distribution .iter() @@ -365,6 +381,7 @@ impl WeightedListIntProvider { self.distribution.last().unwrap().data.get(random) } + #[must_use] pub fn get_max(&self) -> i32 { self.distribution .iter() @@ -392,6 +409,7 @@ impl ToTokens for UniformIntProvider { } impl UniformIntProvider { + #[must_use] pub fn new(min_inclusive: i32, max_inclusive: i32) -> Self { Self { min_inclusive, @@ -399,6 +417,7 @@ impl UniformIntProvider { } } + #[must_use] pub fn get_min(&self) -> i32 { self.min_inclusive } @@ -407,6 +426,7 @@ impl UniformIntProvider { random.next_inbetween_i32(self.min_inclusive, self.max_inclusive) } + #[must_use] pub fn get_max(&self) -> i32 { self.max_inclusive } diff --git a/pumpkin-util/src/math/mod.rs b/pumpkin-util/src/math/mod.rs index 8709e0335..938b9cf48 100644 --- a/pumpkin-util/src/math/mod.rs +++ b/pumpkin-util/src/math/mod.rs @@ -12,6 +12,7 @@ pub mod vector2; pub mod vector3; pub mod vertical_surface_type; +#[must_use] pub fn wrap_degrees(degrees: f32) -> f32 { let mut var1 = degrees % 360.0; if var1 >= 180.0 { @@ -25,26 +26,31 @@ pub fn wrap_degrees(degrees: f32) -> f32 { var1 } +#[must_use] pub fn clamp_angle(value: f32, mean: f32, delta: f32) -> f32 { let i = subtract_angles(value, mean); let j = i.clamp(-delta, delta); mean - j } +#[must_use] pub fn subtract_angles(start: f32, end: f32) -> f32 { wrap_degrees(end - start) } +#[must_use] pub fn squared_magnitude(a: f64, b: f64, c: f64) -> f64 { c.mul_add(c, a.mul_add(a, b * b)) } +#[must_use] pub fn magnitude(a: f64, b: f64, c: f64) -> f64 { squared_magnitude(a, b, c).sqrt() } /// Converts a world coordinate to the corresponding chunk-section coordinate. // TODO: This probably shouldn't be placed here +#[must_use] pub const fn get_section_cord(coord: i32) -> i32 { coord >> 4 } @@ -55,6 +61,7 @@ const MULTIPLY_DE_BRUIJN_BIT_POSITION: [u8; 32] = [ ]; /// Maximum return value: 31 +#[must_use] pub const fn ceil_log2(value: u32) -> u8 { let value = if value.is_power_of_two() { value @@ -66,10 +73,12 @@ pub const fn ceil_log2(value: u32) -> u8 { } /// Maximum return value: 30 +#[must_use] pub const fn floor_log2(value: u32) -> u8 { ceil_log2(value) - if value.is_power_of_two() { 0 } else { 1 } } +#[must_use] pub const fn smallest_encompassing_power_of_two(value: u32) -> u32 { value.next_power_of_two() } @@ -116,6 +125,7 @@ pub fn lerp_progress(value: T, start: T, end: T) -> T { (value - start) / (end - start) } +#[must_use] pub fn clamped_lerp(start: f64, end: f64, delta: f64) -> f64 { if delta < 0.0 { start @@ -127,10 +137,12 @@ pub fn clamped_lerp(start: f64, end: f64, delta: f64) -> f64 { } #[inline] +#[must_use] pub fn clamped_map(value: f64, old_start: f64, old_end: f64, new_start: f64, new_end: f64) -> f64 { clamped_lerp(new_start, new_end, lerp_progress(value, old_start, old_end)) } +#[must_use] pub fn lerp2(delta_x: f64, delta_y: f64, x0y0: f64, x1y0: f64, x0y1: f64, x1y1: f64) -> f64 { lerp( delta_y, @@ -140,6 +152,7 @@ pub fn lerp2(delta_x: f64, delta_y: f64, x0y0: f64, x1y0: f64, x0y1: f64, x1y1: } #[expect(clippy::too_many_arguments)] +#[must_use] pub fn lerp3( delta_x: f64, delta_y: f64, @@ -162,10 +175,11 @@ pub fn lerp3( /// Calculates a Polynomial Rolling Hash /// Mojang's checksum algorithm for previous messages +#[must_use] pub fn polynomial_rolling_hash(signatures: &[Box<[u8]>]) -> u8 { let mut i: i32 = 1; - for signature in signatures.iter() { + for signature in signatures { i = i.wrapping_mul(31).wrapping_add(java_array_hash(signature)); // Wrap to prevent multiplication overflow } @@ -173,7 +187,7 @@ pub fn polynomial_rolling_hash(signatures: &[Box<[u8]>]) -> u8 { if b == 0 { 1 } else { b } // Ensure the checksum is never zero. } -/// Arrays.hashCode() and String.hashCode() have similar but different implementations. +/// `Arrays.hashCode()` and `String.hashCode()` have similar but different implementations. fn java_array_hash(data: &[u8]) -> i32 { let mut hash: i32 = 1; for &byte in data { @@ -183,6 +197,7 @@ fn java_array_hash(data: &[u8]) -> i32 { hash } +#[must_use] pub fn java_string_hash(string: &str) -> i32 { let mut result = 0i32; for char_encoding in string.encode_utf16() { @@ -194,6 +209,7 @@ pub fn java_string_hash(string: &str) -> i32 { } #[test] +#[expect(clippy::unicode_not_nfc)] fn test_java_hash() { let values = [ ("", 0, 1), diff --git a/pumpkin-util/src/math/pool.rs b/pumpkin-util/src/math/pool.rs index ef44c7e24..ac5f3b8eb 100644 --- a/pumpkin-util/src/math/pool.rs +++ b/pumpkin-util/src/math/pool.rs @@ -14,15 +14,14 @@ impl Pool { let mut index = random.next_bounded_i32(total_weight); if total_weight < 64 { return Some(FlattenedContent::get(index, distribution, total_weight)); - } else { - // WrappedContent - for dist in distribution { - index -= dist.weight; - if index >= 0 { - continue; - } - return Some(dist.data.clone()); + } + // WrappedContent + for dist in distribution { + index -= dist.weight; + if index >= 0 { + continue; } + return Some(dist.data.clone()); } None } diff --git a/pumpkin-util/src/math/position.rs b/pumpkin-util/src/math/position.rs index 9fa0e31c9..1c57c1b52 100644 --- a/pumpkin-util/src/math/position.rs +++ b/pumpkin-util/src/math/position.rs @@ -20,6 +20,7 @@ pub struct BlockPosIterator { } impl BlockPosIterator { + #[must_use] pub fn new( start_x: i32, start_y: i32, @@ -32,7 +33,7 @@ impl BlockPosIterator { let count_y = end_y - start_y + 1; let count_z = end_z - start_z + 1; let count = (count_x * count_y * count_z) as usize; - BlockPosIterator { + Self { start_x, start_y, start_z, @@ -87,9 +88,10 @@ pub struct OutwardIterator { } impl OutwardIterator { + #[must_use] pub fn new(center: BlockPos, range_x: i32, range_y: i32, range_z: i32) -> Self { let max_manhattan_distance = range_x + range_y + range_z; - OutwardIterator { + Self { center_x: center.0.x, center_y: center.0.y, center_z: center.0.z, @@ -156,6 +158,7 @@ pub struct BlockPos(pub Vector3); impl BlockPos { pub const ZERO: Self = Self::new(0, 0, 0); + #[must_use] pub const fn new(x: i32, y: i32, z: i32) -> Self { Self(Vector3::new(x, y, z)) } @@ -176,7 +179,8 @@ impl BlockPos { /// # Returns /// /// A `BlockPosIterator` that yields each `BlockPos` within the defined cuboid. - pub fn iterate(start: BlockPos, end: BlockPos) -> BlockPosIterator { + #[must_use] + pub fn iterate(start: Self, end: Self) -> BlockPosIterator { BlockPosIterator::new( start.0.x.min(end.0.x), start.0.y.min(end.0.y), @@ -205,8 +209,9 @@ impl BlockPos { /// # Returns /// /// An `OutwardIterator` that yields `BlockPos` instances in the described outward order. + #[must_use] pub fn iterate_outwards( - center: BlockPos, + center: Self, range_x: i32, range_y: i32, range_z: i32, @@ -214,6 +219,7 @@ impl BlockPos { OutwardIterator::new(center, range_x, range_y, range_z) } + #[must_use] pub fn iterate_block_pos( start_x: i32, start_y: i32, @@ -225,10 +231,12 @@ impl BlockPos { BlockPosIterator::new(start_x, start_y, start_z, end_x, end_y, end_z) } + #[must_use] pub fn chunk_and_chunk_relative_position(&self) -> (Vector2, Vector3) { (self.chunk_position(), self.chunk_relative_position()) } + #[must_use] pub fn chunk_position(&self) -> Vector2 { let z_chunk = self.0.z.div_euclid(16); let x_chunk = self.0.x.div_euclid(16); @@ -238,6 +246,7 @@ impl BlockPos { } } + #[must_use] pub fn chunk_relative_position(&self) -> Vector3 { let z_chunk = self.0.z.rem_euclid(16); let x_chunk = self.0.x.rem_euclid(16); @@ -248,6 +257,7 @@ impl BlockPos { } } + #[must_use] pub fn section_relative_position(&self) -> Vector3 { let (_z_chunk, z_rem) = self.0.z.div_rem_euclid(&16); let (_x_chunk, x_rem) = self.0.x.div_rem_euclid(&16); @@ -260,14 +270,16 @@ impl BlockPos { y: y_rem, } } + #[must_use] pub fn from_i64(encoded_position: i64) -> Self { - BlockPos(Vector3 { + Self(Vector3 { x: (encoded_position >> 38) as i32, y: (encoded_position << 52 >> 52) as i32, z: (encoded_position << 26 >> 38) as i32, }) } + #[must_use] pub fn floored(x: f64, y: f64, z: f64) -> Self { Self(Vector3::new( x.floor() as i32, @@ -276,6 +288,7 @@ impl BlockPos { )) } + #[must_use] pub fn floored_v(pos: Vector3) -> Self { Self(Vector3::new( pos.x.floor() as i32, @@ -284,6 +297,7 @@ impl BlockPos { )) } + #[must_use] pub fn ceiled_v(pos: Vector3) -> Self { Self(Vector3::new( pos.x.ceil() as i32, @@ -292,70 +306,84 @@ impl BlockPos { )) } + #[must_use] pub fn to_f64(&self) -> Vector3 { Vector3::new( - self.0.x as f64 + 0.5, - self.0.y as f64, - self.0.z as f64 + 0.5, + f64::from(self.0.x) + 0.5, + f64::from(self.0.y), + f64::from(self.0.z) + 0.5, ) } + #[must_use] pub fn to_centered_f64(&self) -> Vector3 { Vector3::new( - self.0.x as f64 + 0.5, - self.0.y as f64 + 0.5, - self.0.z as f64 + 0.5, + f64::from(self.0.x) + 0.5, + f64::from(self.0.y) + 0.5, + f64::from(self.0.z) + 0.5, ) } + #[must_use] pub fn offset(&self, offset: Vector3) -> Self { - BlockPos(self.0 + offset) + Self(self.0 + offset) } + #[must_use] pub fn add(&self, x: i32, y: i32, z: i32) -> Self { - BlockPos::new(self.0.x + x, self.0.y + y, self.0.z + z) + Self::new(self.0.x + x, self.0.y + y, self.0.z + z) } + #[must_use] pub fn offset_dir(&self, offset: Vector3, direction: i32) -> Self { - BlockPos(Vector3::new( + Self(Vector3::new( self.0.x + offset.x * direction, self.0.y + offset.y * direction, self.0.z + offset.z * direction, )) } + #[must_use] pub fn up(&self) -> Self { self.offset(Vector3::new(0, 1, 0)) } + #[must_use] pub fn up_height(&self, height: i32) -> Self { self.offset(Vector3::new(0, height, 0)) } + #[must_use] pub fn down(&self) -> Self { self.offset(Vector3::new(0, -1, 0)) } + #[must_use] pub fn down_height(&self, height: i32) -> Self { self.offset(Vector3::new(0, -height, 0)) } + #[must_use] pub fn west(&self) -> Self { self.offset(Vector3::new(-1, 0, 0)) } + #[must_use] pub fn north(&self) -> Self { self.offset(Vector3::new(0, 0, -1)) } + #[must_use] pub fn east(&self) -> Self { self.offset(Vector3::new(1, 0, 0)) } + #[must_use] pub fn south(&self) -> Self { self.offset(Vector3::new(0, 0, 1)) } + #[must_use] pub fn manhattan_distance(&self, other: Self) -> i32 { let x = (other.0.x - self.0.x).abs(); let y = (other.0.y - self.0.y).abs(); @@ -363,14 +391,16 @@ impl BlockPos { x + y + z } + #[must_use] pub fn squared_distance(&self, other: &Self) -> i32 { self.0.squared_distance_to_vec(&other.0) } + #[must_use] pub fn as_long(&self) -> i64 { - ((self.0.x as i64 & 0x3FFFFFF) << 38) - | ((self.0.z as i64 & 0x3FFFFFF) << 12) - | (self.0.y as i64 & 0xFFF) + ((i64::from(self.0.x) & 0x03FF_FFFF) << 38) + | ((i64::from(self.0.z) & 0x03FF_FFFF) << 12) + | (i64::from(self.0.y) & 0xFFF) } } @@ -416,6 +446,7 @@ pub const fn chunk_section_from_pos(block_pos: &BlockPos) -> Vector3 { ) } +#[must_use] pub const fn get_local_cord(cord: i32) -> i32 { cord & 15 } diff --git a/pumpkin-util/src/math/vector2.rs b/pumpkin-util/src/math/vector2.rs index e3aa8cf53..8b5a930de 100644 --- a/pumpkin-util/src/math/vector2.rs +++ b/pumpkin-util/src/math/vector2.rs @@ -13,34 +13,38 @@ pub struct Vector2 { impl Vector2 { pub const fn new(x: T, y: T) -> Self { - Vector2 { x, y } + Self { x, y } } pub fn length_squared(&self) -> T { self.x * self.x + self.y * self.y } - pub fn add(&self, other: &Vector2) -> Self { - Vector2 { + #[must_use] + pub fn add(&self, other: &Self) -> Self { + Self { x: self.x + other.x, y: self.y + other.y, } } + #[must_use] pub fn add_raw(&self, x: T, y: T) -> Self { - Vector2 { + Self { x: self.x + x, y: self.y + y, } } - pub fn sub(&self, other: &Vector2) -> Self { - Vector2 { + #[must_use] + pub fn sub(&self, other: &Self) -> Self { + Self { x: self.x - other.x, y: self.y - other.y, } } + #[must_use] pub fn multiply(self, x: T, y: T) -> Self { Self { x: self.x * x, @@ -53,9 +57,11 @@ impl Vector2 { pub fn length(&self) -> T { self.length_squared().sqrt() } + + #[must_use] pub fn normalize(&self) -> Self { let length = self.length(); - Vector2 { + Self { x: self.x / length, y: self.y / length, } @@ -74,7 +80,7 @@ impl Mul for Vector2 { } impl Add for Vector2 { - type Output = Vector2; + type Output = Self; fn add(self, rhs: Self) -> Self::Output { Self { x: self.x + rhs.x, @@ -87,7 +93,7 @@ impl Neg for Vector2 { type Output = Self; fn neg(self) -> Self { - Vector2 { + Self { x: -self.x, y: -self.y, } @@ -96,7 +102,7 @@ impl Neg for Vector2 { impl From<(T, T)> for Vector2 { fn from((x, z): (T, T)) -> Self { - Vector2 { x, y: z } + Self { x, y: z } } } @@ -124,13 +130,14 @@ impl Math for i32 {} impl Math for i64 {} impl Math for i8 {} +#[must_use] pub const fn to_chunk_pos(vec: &Vector2) -> Vector2 { Vector2::new(vec.x >> 4, vec.y >> 4) } impl serde::Serialize for Vector2 { fn serialize(&self, serializer: S) -> Result { - let mut buf = Vec::with_capacity(size_of::>()); + let mut buf = Vec::with_capacity(size_of::()); buf.put_f32(self.x); buf.put_f32(self.y); serializer.serialize_bytes(&buf) diff --git a/pumpkin-util/src/math/vector3.rs b/pumpkin-util/src/math/vector3.rs index fa700ccf4..7cdad6166 100644 --- a/pumpkin-util/src/math/vector3.rs +++ b/pumpkin-util/src/math/vector3.rs @@ -24,14 +24,17 @@ pub enum Axis { } impl Axis { + #[must_use] pub fn all() -> [Self; 3] { [Self::Y, Self::X, Self::Z] } + #[must_use] pub fn horizontal() -> [Self; 2] { [Self::X, Self::Z] } + #[must_use] pub fn excluding(axis: Self) -> [Self; 2] { match axis { Self::X => [Self::Y, Self::Z], @@ -57,55 +60,63 @@ impl Vector3 { Axis::X => self.x = value, Axis::Y => self.y = value, Axis::Z => self.z = value, - }; + } } } impl Vector3 { + #[must_use] pub const fn new(x: T, y: T, z: T) -> Self { - Vector3 { x, y, z } + Self { x, y, z } } + #[must_use] pub fn length_squared(&self) -> T { self.x * self.x + self.y * self.y + self.z * self.z } + #[must_use] pub fn horizontal_length_squared(&self) -> T { self.x * self.x + self.z * self.z } - pub fn add(&self, other: &Vector3) -> Self { - Vector3 { + #[must_use] + pub fn add(&self, other: &Self) -> Self { + Self { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z, } } + #[must_use] pub fn add_raw(&self, x: T, y: T, z: T) -> Self { - Vector3 { + Self { x: self.x + x, y: self.y + y, z: self.z + z, } } - pub fn sub(&self, other: &Vector3) -> Self { - Vector3 { + #[must_use] + pub fn sub(&self, other: &Self) -> Self { + Self { x: self.x - other.x, y: self.y - other.y, z: self.z - other.z, } } + #[must_use] pub fn sub_raw(&self, x: T, y: T, z: T) -> Self { - Vector3 { + Self { x: self.x - x, y: self.y - y, z: self.z - z, } } + #[must_use] pub fn multiply(self, x: T, y: T, z: T) -> Self { Self { x: self.x * x, @@ -114,14 +125,16 @@ impl Vector3 { } } - pub fn lerp(&self, other: &Vector3, t: T) -> Self { - Vector3 { + #[must_use] + pub fn lerp(&self, other: &Self, t: T) -> Self { + Self { x: self.x + (other.x - self.x) * t, y: self.y + (other.y - self.y) * t, z: self.z + (other.z - self.z) * t, } } + #[must_use] pub fn sign(&self) -> Vector3 where T: Num + PartialOrd + Copy, @@ -151,10 +164,12 @@ impl Vector3 { } } + #[must_use] pub fn squared_distance_to_vec(&self, other: &Self) -> T { self.squared_distance_to(other.x, other.y, other.z) } + #[must_use] pub fn squared_distance_to(&self, x: T, y: T, z: T) -> T { let delta_x = self.x - x; let delta_y = self.y - y; @@ -162,6 +177,7 @@ impl Vector3 { delta_x * delta_x + delta_y * delta_y + delta_z * delta_z } + #[must_use] pub fn is_within_bounds(&self, block_pos: Self, x: T, y: T, z: T) -> bool { let min_x = block_pos.x - x; let max_x = block_pos.x + x; @@ -188,9 +204,10 @@ impl Vector3 { self.horizontal_length_squared().sqrt() } + #[must_use] pub fn normalize(&self) -> Self { let length = self.length(); - Vector3 { + Self { x: self.x / length, y: self.y / length, z: self.z / length, @@ -223,7 +240,7 @@ impl Mul for Vector3 { } impl Add for Vector3 { - type Output = Vector3; + type Output = Self; fn add(self, rhs: Self) -> Self::Output { Self { x: self.x + rhs.x, @@ -234,7 +251,7 @@ impl Add for Vector3 { } impl Sub for Vector3 { - type Output = Vector3; + type Output = Self; fn sub(self, rhs: Self) -> Self::Output { Self { x: self.x - rhs.x, @@ -267,14 +284,12 @@ impl Neg for Vector3 { */ impl From<(T, T, T)> for Vector3 { - #[inline(always)] fn from((x, y, z): (T, T, T)) -> Self { - Vector3 { x, y, z } + Self { x, y, z } } } impl From> for (T, T, T) { - #[inline(always)] fn from(vector: Vector3) -> Self { (vector.x, vector.y, vector.z) } @@ -473,16 +488,18 @@ impl serde::Serialize for Vector3 { } #[inline] +#[must_use] pub const fn packed_chunk_pos(vec: &Vector3) -> i64 { let mut result = 0i64; // Need to go to i64 first to conserve sign - result |= (vec.x as i64 & 0x3FFFFF) << 42; - result |= (vec.z as i64 & 0x3FFFFF) << 20; + result |= (vec.x as i64 & 0x03FF_FFFF) << 42; + result |= (vec.z as i64 & 0x003F_FFFF) << 20; result |= vec.y as i64 & 0xFFFFF; result } #[inline] +#[must_use] pub const fn packed_local(vec: &Vector3) -> i16 { let x = vec.x as i16; let y = vec.y as i16; diff --git a/pumpkin-util/src/noise/mod.rs b/pumpkin-util/src/noise/mod.rs index f01e9ddb3..a3893c779 100644 --- a/pumpkin-util/src/noise/mod.rs +++ b/pumpkin-util/src/noise/mod.rs @@ -92,6 +92,7 @@ pub const GRADIENTS: [Gradient; 16] = [ impl Gradient { #[inline] + #[must_use] pub fn dot(&self, x: f64, y: f64, z: f64) -> f64 { self.x * x + self.y * y + self.z * z } diff --git a/pumpkin-util/src/noise/perlin.rs b/pumpkin-util/src/noise/perlin.rs index f1de4dd99..a2217de3b 100644 --- a/pumpkin-util/src/noise/perlin.rs +++ b/pumpkin-util/src/noise/perlin.rs @@ -40,10 +40,12 @@ impl PerlinNoiseSampler { } #[inline] + #[must_use] pub fn sample_flat_y(&self, x: f64, y: f64, z: f64) -> f64 { self.sample_no_fade(x, y, z, 0.0, 0.0) } + #[must_use] pub fn sample_no_fade(&self, x: f64, y: f64, z: f64, y_scale: f64, y_max: f64) -> f64 { let true_x = x + self.x_origin; let true_y = y + self.y_origin; @@ -57,15 +59,15 @@ impl PerlinNoiseSampler { let y_dec = true_y - y_floor; let z_dec = true_z - z_floor; - let y_noise = if y_scale != 0.0 { + let y_noise = if y_scale == 0.0 { + 0.0 + } else { let raw_y_dec = if y_max >= 0.0 && y_max < y_dec { y_max } else { y_dec }; (raw_y_dec / y_scale + 1E-7).floor() * y_scale - } else { - 0.0 }; self.sample( @@ -91,10 +93,11 @@ impl PerlinNoiseSampler { #[inline] fn map(&self, input: i32) -> i32 { - self.permutation[(input & 0xFF) as usize] as i32 + i32::from(self.permutation[(input & 0xFF) as usize]) } #[expect(clippy::too_many_arguments)] + #[expect(clippy::many_single_char_names)] fn sample( &self, x: i32, @@ -147,6 +150,7 @@ pub struct OctavePerlinNoiseSampler { } impl OctavePerlinNoiseSampler { + #[must_use] pub fn max_value(&self) -> f64 { self.max_value } @@ -156,20 +160,22 @@ impl OctavePerlinNoiseSampler { .iter() .zip(persistences) .map(|(amplitude, persistence)| { - if *amplitude != 0.0 { - scale * *amplitude * *persistence - } else { + if *amplitude == 0.0 { 0.0 + } else { + scale * *amplitude * *persistence } }) .sum() } #[inline] + #[must_use] pub fn maintain_precision(value: f64) -> f64 { - value - (value / 3.3554432E7 + 0.5).floor() * 3.3554432E7 + value - (value / 3.355_443_2E7 + 0.5).floor() * 3.355_443_2E7 } + #[must_use] pub fn calculate_amplitudes(octaves: &[i32]) -> (i32, Vec) { let mut octaves = Vec::from_iter(octaves); octaves.sort(); @@ -178,10 +184,7 @@ impl OctavePerlinNoiseSampler { let j = **octaves.last().expect("we should have some octaves"); let k = i + j + 1; - let mut double_list: Vec = Vec::with_capacity(k as usize); - for _ in 0..k { - double_list.push(0.0) - } + let mut double_list = vec![0.0; k as usize]; for l in octaves { double_list[(l + i) as usize] = 1.0; @@ -213,10 +216,10 @@ impl OctavePerlinNoiseSampler { for kx in (0..j as usize).rev() { if kx < i { let e = amplitudes[kx]; - if e != 0.0 { - samplers[kx] = Some(PerlinNoiseSampler::new(random)); - } else { + if e == 0.0 { random.skip(262); + } else { + samplers[kx] = Some(PerlinNoiseSampler::new(random)); } } else { random.skip(262); @@ -274,6 +277,7 @@ impl OctavePerlinNoiseSampler { } #[inline] + #[must_use] pub fn get_total_amplitude(&self, scale: f64) -> f64 { self.samplers .iter() @@ -282,6 +286,7 @@ impl OctavePerlinNoiseSampler { } #[inline] + #[must_use] pub fn sample(&self, x: f64, y: f64, z: f64) -> f64 { self.samplers .iter() @@ -392,6 +397,7 @@ mod tests { } #[test] + #[expect(clippy::too_many_lines)] fn test_no_y() { let mut rand = Xoroshiro::from_seed(111); assert_eq!(rand.next_i32(), -1467508761); @@ -590,6 +596,7 @@ mod tests { } #[test] + #[expect(clippy::too_many_lines)] fn test_no_fade() { let mut rand = Xoroshiro::from_seed(111); assert_eq!(rand.next_i32(), -1467508761); diff --git a/pumpkin-util/src/noise/simplex.rs b/pumpkin-util/src/noise/simplex.rs index 30ed58bf6..e08312950 100644 --- a/pumpkin-util/src/noise/simplex.rs +++ b/pumpkin-util/src/noise/simplex.rs @@ -66,7 +66,7 @@ impl SimplexNoiseSampler { #[inline] fn map(&self, input: i32) -> i32 { - self.permutation[(input & 0xFF) as usize] as i32 + i32::from(self.permutation[(input & 0xFF) as usize]) } fn grad(gradient_index: usize, x: f64, y: f64, z: f64, distance: f64) -> f64 { @@ -79,22 +79,24 @@ impl SimplexNoiseSampler { } } + #[must_use] + #[expect(clippy::many_single_char_names)] pub fn sample_2d(&self, x: f64, y: f64) -> f64 { let d = (x + y) * Self::SKEW_FACTOR_2D; let i = (x + d).floor() as i32; let j = (y + d).floor() as i32; - let e = (i.wrapping_add(j)) as f64 * Self::UNSKEW_FACTOR_2D; - let f = i as f64 - e; - let g = j as f64 - e; + let e = f64::from(i.wrapping_add(j)) * Self::UNSKEW_FACTOR_2D; + let f = f64::from(i) - e; + let g = f64::from(j) - e; let h = x - f; let k = y - g; let (l, m) = if h > k { (1, 0) } else { (0, 1) }; - let n = h - l as f64 + Self::UNSKEW_FACTOR_2D; - let o = k - m as f64 + Self::UNSKEW_FACTOR_2D; + let n = h - f64::from(l) + Self::UNSKEW_FACTOR_2D; + let o = k - f64::from(m) + Self::UNSKEW_FACTOR_2D; let p = 2.0 * Self::UNSKEW_FACTOR_2D + (h - 1.0); let q = 2.0 * Self::UNSKEW_FACTOR_2D + (k - 1.0); @@ -112,6 +114,8 @@ impl SimplexNoiseSampler { 70.0 * (w + z + aa) } + #[must_use] + #[expect(clippy::many_single_char_names)] pub fn sample_3d(&self, x: f64, y: f64, z: f64) -> f64 { let e = (x + y + z) * 0.3333333333333333; @@ -119,10 +123,10 @@ impl SimplexNoiseSampler { let j = (y + e).floor() as i32; let k = (z + e).floor() as i32; - let g = (i.wrapping_add(j).wrapping_add(k)) as f64 * 0.16666666666666666; - let h = i as f64 - g; - let l = j as f64 - g; - let m = k as f64 - g; + let g = f64::from(i.wrapping_add(j).wrapping_add(k)) * 0.16666666666666666; + let h = f64::from(i) - g; + let l = f64::from(j) - g; + let m = f64::from(k) - g; let n = x - h; let o = y - l; @@ -144,13 +148,13 @@ impl SimplexNoiseSampler { (0, 1, 0, 1, 1, 0) }; - let w = n - q as f64 + 0.16666666666666666; - let aa = o - r as f64 + 0.16666666666666666; - let ab = p - s as f64 + 0.16666666666666666; + let w = n - f64::from(q) + 0.16666666666666666; + let aa = o - f64::from(r) + 0.16666666666666666; + let ab = p - f64::from(s) + 0.16666666666666666; - let ac = n - t as f64 + 0.3333333333333333; - let ad = o - u as f64 + 0.3333333333333333; - let ae = p - v as f64 + 0.3333333333333333; + let ac = n - f64::from(t) + 0.3333333333333333; + let ad = o - f64::from(u) + 0.3333333333333333; + let ae = p - f64::from(v) + 0.3333333333333333; let af = n - 1.0 + 0.5; let ag = o - 1.0 + 0.5; @@ -202,6 +206,7 @@ pub struct OctaveSimplexNoiseSampler { } impl OctaveSimplexNoiseSampler { + #[expect(clippy::many_single_char_names)] pub fn new(random: &mut impl RandomImpl, octaves: &[i32]) -> Self { let mut octaves = Vec::from_iter(octaves); octaves.sort(); @@ -228,10 +233,10 @@ impl OctaveSimplexNoiseSampler { if j > 0 { let sample = sampler.sample_3d(sampler.x_origin, sampler.y_origin, sampler.z_origin); - let n = (sample * 9.223372E18f32 as f64) as i64; + let n = (sample * f64::from(9.223372E18f32)) as i64; let mut random = LegacyRand::from_seed(n as u64); - for o in (0..=(l - 1)).rev() { + for o in (0..l).rev() { if o < k && octaves.contains(&&(l - o)) { let sampler = SimplexNoiseSampler::new(&mut random); samplers[o as usize] = Some(sampler); @@ -252,12 +257,14 @@ impl OctaveSimplexNoiseSampler { } } + #[must_use] + #[expect(clippy::many_single_char_names)] pub fn sample(&self, x: f64, y: f64, use_origin: bool) -> f64 { let mut d = 0.0; let mut e = self.lacunarity; let mut f = self.persistence; - for sampler in self.octave_samplers.iter() { + for sampler in &self.octave_samplers { if let Some(sampler) = sampler { d += sampler.sample_2d( x * e + if use_origin { sampler.x_origin } else { 0.0 }, @@ -445,6 +452,7 @@ mod simplex_noise_sampler_test { } #[test] + #[expect(clippy::too_many_lines)] fn test_sample_2d() { let data1 = [ ((-50000, 0), -0.013008608535752102), @@ -556,6 +564,7 @@ mod simplex_noise_sampler_test { } #[test] + #[expect(clippy::too_many_lines)] fn test_sample_3d() { let data = [ ( diff --git a/pumpkin-util/src/permission.rs b/pumpkin-util/src/permission.rs index 9c3094ed4..a4193f73e 100644 --- a/pumpkin-util/src/permission.rs +++ b/pumpkin-util/src/permission.rs @@ -28,6 +28,7 @@ pub struct Permission { } impl Permission { + #[must_use] pub fn new(node: &str, description: &str, default: PermissionDefault) -> Self { Self { node: node.to_string(), @@ -52,6 +53,7 @@ pub struct PermissionRegistry { } impl PermissionRegistry { + #[must_use] pub fn new() -> Self { Self { permissions: HashMap::new(), @@ -71,11 +73,13 @@ impl PermissionRegistry { } /// Get a registered permission by node + #[must_use] pub fn get_permission(&self, node: &str) -> Option<&Permission> { self.permissions.get(node) } /// Check if a permission is registered + #[must_use] pub fn has_permission(&self, node: &str) -> bool { self.permissions.contains_key(node) } @@ -89,6 +93,7 @@ pub struct PermissionAttachment { } impl PermissionAttachment { + #[must_use] pub fn new() -> Self { Self { permissions: HashMap::new(), @@ -106,11 +111,13 @@ impl PermissionAttachment { } /// Check if a permission is directly set + #[must_use] pub fn has_permission_set(&self, node: &str) -> Option { self.permissions.get(node).copied() } /// Get all directly set permissions + #[must_use] pub fn get_permissions(&self) -> &HashMap { &self.permissions } @@ -206,16 +213,12 @@ impl PermissionManager { } // Fall back to default permission value - if let Some(permission) = reg.get_permission(permission_node) { - match permission.default { + reg.get_permission(permission_node) + .is_some_and(|permission| match permission.default { PermissionDefault::Allow => true, PermissionDefault::Deny => false, PermissionDefault::Op(required_level) => player_op_level >= required_level, - } - } else { - // If permission isn't registered, default to deny - false - } + }) } } @@ -263,10 +266,10 @@ impl<'de> Deserialize<'de> for PermissionLvl { fn deserialize>(deserializer: D) -> Result { let value = u8::deserialize(deserializer)?; match value { - 0 => Ok(PermissionLvl::Zero), - 2 => Ok(PermissionLvl::Two), - 3 => Ok(PermissionLvl::Three), - 4 => Ok(PermissionLvl::Four), + 0 => Ok(Self::Zero), + 2 => Ok(Self::Two), + 3 => Ok(Self::Three), + 4 => Ok(Self::Four), _ => Err(serde::de::Error::custom(format!( "Invalid value for OpLevel: {value}" ))), diff --git a/pumpkin-util/src/random/legacy_rand.rs b/pumpkin-util/src/random/legacy_rand.rs index 5ec96c0b5..d4e662d79 100644 --- a/pumpkin-util/src/random/legacy_rand.rs +++ b/pumpkin-util/src/random/legacy_rand.rs @@ -13,16 +13,17 @@ pub struct LegacyRand { impl LegacyRand { population_seed_fn!(); + #[must_use] pub fn from_seed(seed: u64) -> Self { - LegacyRand { - seed: (seed ^ 0x5DEECE66D) & 0xFFFFFFFFFFFF, + Self { + seed: (seed ^ 0x0005_DEEC_E66D) & 0xFFFF_FFFF_FFFF, internal_next_gaussian: None, } } fn next_random(&mut self) -> i64 { let l = self.seed as i64; - let m = l.wrapping_mul(0x5DEECE66D).wrapping_add(11) & 0xFFFFFFFFFFFF; + let m = l.wrapping_mul(0x0005_DEEC_E66D).wrapping_add(11) & 0xFFFFFFFFFFFF; self.seed = m as u64; m } @@ -44,7 +45,7 @@ impl GaussianGenerator for LegacyRand { impl RandomImpl for LegacyRand { fn split(&mut self) -> Self { - LegacyRand::from_seed(self.next_i64() as u64) + Self::from_seed(self.next_i64() as u64) } fn next_i32(&mut self) -> i32 { @@ -54,7 +55,7 @@ impl RandomImpl for LegacyRand { fn next_i64(&mut self) -> i64 { let i = self.next_i32(); let j = self.next_i32(); - ((i as i64) << 32).wrapping_add(j as i64) + (i64::from(i) << 32).wrapping_add(i64::from(j)) } fn next_f32(&mut self) -> f32 { @@ -64,8 +65,8 @@ impl RandomImpl for LegacyRand { fn next_f64(&mut self) -> f64 { let i = self.next(26); let j = self.next(27); - let l = ((i as i64) << 27).wrapping_add(j as i64); - l as f64 * 1.110223E-16f32 as f64 + let l = (i64::from(i) << 27).wrapping_add(i64::from(j)); + l as f64 * f64::from(1.110223E-16f32) } fn next_bool(&mut self) -> bool { @@ -82,7 +83,7 @@ impl RandomImpl for LegacyRand { fn next_bounded_i32(&mut self, bound: i32) -> i32 { if (bound & bound.wrapping_sub(1)) == 0 { - ((bound as i64).wrapping_mul(self.next(31) as i64) >> 31) as i32 + (i64::from(bound).wrapping_mul(i64::from(self.next(31))) >> 31) as i32 } else { loop { let i = self.next(31); @@ -102,7 +103,7 @@ pub struct LegacySplitter { impl LegacySplitter { fn new(seed: u64) -> Self { - LegacySplitter { seed } + Self { seed } } } @@ -318,15 +319,14 @@ mod test { let mut original_rand = LegacyRand::from_seed(0); { - let splitter = match original_rand.next_splitter() { - RandomDeriver::Legacy(splitter) => splitter, - _ => unreachable!(), + let RandomDeriver::Legacy(splitter) = original_rand.next_splitter() else { + unreachable!() }; assert_eq!(splitter.seed, (-4962768465676381896i64) as u64); let mut rand = splitter.split_string("minecraft:offset"); assert_eq!(rand.next_i32(), 103436829); - } + }; let mut original_rand = LegacyRand::from_seed(0); let mut new_rand = original_rand.split(); @@ -341,7 +341,7 @@ mod test { let mut rand3 = splitter.split_pos(1, 11, -111); assert_eq!(rand3.next_i32(), -1213890343); - } + }; assert_eq!(original_rand.next_i32(), 1033096058); assert_eq!(new_rand.next_i32(), -888301832); diff --git a/pumpkin-util/src/random/mod.rs b/pumpkin-util/src/random/mod.rs index f6422461f..13e7f1452 100644 --- a/pumpkin-util/src/random/mod.rs +++ b/pumpkin-util/src/random/mod.rs @@ -62,6 +62,7 @@ macro_rules! population_seed_fn { // TODO: Write unit test for this #[inline] +#[must_use] pub fn get_decorator_seed(population_seed: u64, index: u64, step: u64) -> u64 { population_seed .wrapping_add(index) @@ -69,14 +70,15 @@ pub fn get_decorator_seed(population_seed: u64, index: u64, step: u64) -> u64 { } #[inline] +#[must_use] pub fn get_region_seed(world_seed: u64, region_x: i32, region_z: i32, salt: u32) -> u64 { - let x_part = (region_x as i64).wrapping_mul(341873128712) as u64; - let z_part = (region_z as i64).wrapping_mul(132897987541) as u64; + let x_part = i64::from(region_x).wrapping_mul(341873128712) as u64; + let z_part = i64::from(region_z).wrapping_mul(132897987541) as u64; world_seed .wrapping_add(x_part) .wrapping_add(z_part) - .wrapping_add(salt as i64 as u64) + .wrapping_add(i64::from(salt) as u64) } #[inline] pub fn get_carver_seed( @@ -91,6 +93,7 @@ pub fn get_carver_seed( } #[enum_dispatch] +#[expect(clippy::return_self_not_must_use)] pub trait RandomImpl { fn split(&mut self) -> Self; @@ -138,8 +141,11 @@ pub trait RandomDeriverImpl { fn split_pos(&self, x: i32, y: i32, z: i32) -> RandomGenerator; } +#[must_use] pub fn hash_block_pos(x: i32, y: i32, z: i32) -> i64 { - let l = (x.wrapping_mul(3129871) as i64) ^ ((z as i64).wrapping_mul(116129781i64)) ^ (y as i64); + let l = i64::from(x.wrapping_mul(3129871)) + ^ (i64::from(z).wrapping_mul(116129781i64)) + ^ i64::from(y); let l = l .wrapping_mul(l) .wrapping_mul(42317861i64) @@ -157,7 +163,7 @@ mod tests { #[test] fn region_seed() { let seed = get_region_seed(12345612, 1, 1, 14357620); - assert_eq!(seed, 474797819485) + assert_eq!(seed, 474797819485); } #[test] diff --git a/pumpkin-util/src/random/xoroshiro128.rs b/pumpkin-util/src/random/xoroshiro128.rs index a6168315b..5e353cc09 100644 --- a/pumpkin-util/src/random/xoroshiro128.rs +++ b/pumpkin-util/src/random/xoroshiro128.rs @@ -14,6 +14,7 @@ pub struct Xoroshiro { impl Xoroshiro { population_seed_fn!(); + #[must_use] pub fn from_seed(seed: u64) -> Self { let (lo, hi) = Self::mix_u64(seed); let lo = mix_stafford_13(lo); @@ -40,6 +41,7 @@ impl Xoroshiro { (l, m) } + #[must_use] pub fn from_seed_unmixed(seed: u64) -> Self { let (lo, hi) = Self::mix_u64(seed); Self::new(lo, hi) @@ -93,15 +95,15 @@ impl RandomImpl for Xoroshiro { } fn next_bounded_i32(&mut self, bound: i32) -> i32 { - let mut l = (self.next_i32() as u64) & 0xFFFFFFFF; + let mut l = (self.next_i32() as u64) & 0xFFFF_FFFF; let mut m = l.wrapping_mul(bound as u64); - let mut n = m & 0xFFFFFFFF; + let mut n = m & 0xFFFF_FFFF; if n < bound as u64 { let i = (((!bound).wrapping_add(1)) as u64) % (bound as u64); while n < i { - l = (self.next_i32() as u64) & 0xFFFFFFFF; + l = (self.next_i32() as u64) & 0xFFFF_FFFF; m = l.wrapping_mul(bound as u64); - n = m & 0xFFFFFFFF; + n = m & 0xFFFF_FFFF; } } let o = m >> 32; @@ -117,11 +119,11 @@ impl RandomImpl for Xoroshiro { } fn next_f32(&mut self) -> f32 { - self.next(24) as f32 * 5.9604645E-8f32 + self.next(24) as f32 * 5.960_464_5E-8f32 } fn next_f64(&mut self) -> f64 { - self.next(53) as f64 * 1.110223E-16f32 as f64 + self.next(53) as f64 * f64::from(1.110_223E-16f32) } fn next_gaussian(&mut self) -> f64 { @@ -136,6 +138,7 @@ pub struct XoroshiroSplitter { } impl RandomDeriverImpl for XoroshiroSplitter { + #[expect(clippy::many_single_char_names)] fn split_pos(&self, x: i32, y: i32, z: i32) -> RandomGenerator { let l = hash_block_pos(x, y, z) as u64; let m = l ^ self.lo; @@ -398,7 +401,7 @@ mod tests { let mut rand_3 = splitter.split_pos(1337, 80085, -69420); assert_eq!(rand_3.next_i32(), 790449132); - } + }; // Verify we didn't mutate the originals assert_eq!(xoroshiro.next_i32(), 653572596); assert_eq!(new_generator.next_i32(), 435917842); diff --git a/pumpkin-util/src/registry.rs b/pumpkin-util/src/registry.rs index 2034e3016..e78ba1061 100644 --- a/pumpkin-util/src/registry.rs +++ b/pumpkin-util/src/registry.rs @@ -9,10 +9,11 @@ pub enum TagType { } impl TagType { + #[must_use] pub fn serialize(&self) -> String { match self { - TagType::Item(name) => name.clone(), - TagType::Tag(tag) => format!("#{tag}"), + Self::Item(name) => name.clone(), + Self::Tag(tag) => format!("#{tag}"), } } } @@ -24,10 +25,10 @@ impl Visitor<'_> for TagVisitor { write!(formatter, "valid tag") } fn visit_str(self, v: &str) -> Result { - match v.strip_prefix('#') { - Some(v) => Ok(TagType::Tag(v.to_string())), - None => Ok(TagType::Item(v.to_string())), - } + v.strip_prefix('#').map_or_else( + || Ok(TagType::Item(v.to_string())), + |v| Ok(TagType::Tag(v.to_string())), + ) } } @@ -44,10 +45,11 @@ pub enum RegistryEntryList { } impl RegistryEntryList { + #[must_use] pub fn into_vec(self) -> Vec { match self { - RegistryEntryList::Single(s) => vec![s], - RegistryEntryList::Many(s) => s, + Self::Single(s) => vec![s], + Self::Many(s) => s, } } } @@ -55,8 +57,8 @@ impl RegistryEntryList { impl PartialEq for RegistryEntryList { fn eq(&self, other: &TagType) -> bool { match self { - RegistryEntryList::Single(ingredient) => other == ingredient, - RegistryEntryList::Many(ingredients) => ingredients.contains(other), + Self::Single(ingredient) => other == ingredient, + Self::Many(ingredients) => ingredients.contains(other), } } } @@ -78,7 +80,7 @@ impl<'de> Deserialize<'de> for RegistryEntryList { fn visit_seq>(self, mut seq: A) -> Result { let mut ingredients: Vec = vec![]; while let Some(element) = seq.next_element()? { - ingredients.push(element) + ingredients.push(element); } if ingredients.len() == 1 { Ok(RegistryEntryList::Single(ingredients[0].clone())) diff --git a/pumpkin-util/src/resource_location.rs b/pumpkin-util/src/resource_location.rs index 094fe1894..74911f888 100644 --- a/pumpkin-util/src/resource_location.rs +++ b/pumpkin-util/src/resource_location.rs @@ -12,14 +12,16 @@ impl ResourceLocation { /// The maximum number of bytes for a [`ResourceLocation`] is the same as for a normal [`String`]. pub const MAX_SIZE: NonZeroUsize = NonZeroUsize::new(i16::MAX as usize).unwrap(); + #[must_use] pub fn from(location: &str) -> Self { - let names = location.split_once(":").unwrap_or_default(); + let names = location.split_once(':').unwrap_or_default(); Self { namespace: names.0.to_string(), path: names.1.to_string(), } } + #[must_use] pub fn vanilla(path: &str) -> Self { Self { namespace: "minecraft".to_string(), @@ -27,6 +29,7 @@ impl ResourceLocation { } } + #[must_use] pub fn pumpkin(path: &str) -> Self { Self { namespace: "pumpkin".to_string(), @@ -45,7 +48,7 @@ impl FromStr for ResourceLocation { type Err = (); fn from_str(s: &str) -> Result { match s.split_once(':') { - Some((namespace, path)) => Ok(ResourceLocation { + Some((namespace, path)) => Ok(Self { namespace: namespace.to_string(), path: path.to_string(), }), @@ -79,7 +82,7 @@ impl<'de> Deserialize<'de> for ResourceLocation { self, resource_location: &str, ) -> Result { - match resource_location.split_once(":") { + match resource_location.split_once(':') { Some((namespace, path)) => Ok(ResourceLocation { namespace: namespace.to_string(), path: path.to_string(), diff --git a/pumpkin-util/src/text/color.rs b/pumpkin-util/src/text/color.rs index 75ee42f72..bd6a87188 100644 --- a/pumpkin-util/src/text/color.rs +++ b/pumpkin-util/src/text/color.rs @@ -16,6 +16,8 @@ pub enum Color { Named(NamedColor), } +#[must_use] +#[expect(clippy::many_single_char_names)] pub fn hsv_to_rgb(h: f32, s: f32, v: f32) -> (u8, u8, u8) { let c = v * s; let x = c * (1.0 - ((h / 60.0) % 2.0 - 1.0).abs()); @@ -40,7 +42,7 @@ impl<'de> Deserialize<'de> for Color { let s = String::deserialize(deserializer)?; if s == "reset" { - Ok(Color::Reset) + Ok(Self::Reset) } else if let Some(hex) = s.strip_prefix('#') { if s.len() != 7 { return Err(serde::de::Error::custom( @@ -55,20 +57,21 @@ impl<'de> Deserialize<'de> for Color { let b = u8::from_str_radix(&hex[4..6], 16) .map_err(|_| serde::de::Error::custom("Invalid blue component in hex color"))?; - Ok(Color::Rgb(RGBColor::new(r, g, b))) + Ok(Self::Rgb(RGBColor::new(r, g, b))) } else { - Ok(Color::Named(NamedColor::try_from(s.as_str()).map_err( - |_| serde::de::Error::custom("Invalid named color"), + Ok(Self::Named(NamedColor::try_from(s.as_str()).map_err( + |()| serde::de::Error::custom("Invalid named color"), )?)) } } } impl Color { + #[must_use] pub fn console_color(&self, text: &str) -> ColoredString { match self { - Color::Reset => text.clear(), - Color::Named(color) => match color { + Self::Reset => text.clear(), + Self::Named(color) => match color { NamedColor::Black => text.black(), NamedColor::DarkBlue => text.blue(), NamedColor::DarkGreen => text.green(), @@ -76,18 +79,17 @@ impl Color { NamedColor::DarkRed => text.red(), NamedColor::DarkPurple => text.purple(), NamedColor::Gold => text.yellow(), - NamedColor::Gray => text.bright_black(), - NamedColor::DarkGray => text.bright_black(), // ? + NamedColor::Gray | NamedColor::DarkGray => text.bright_black(), // ? NamedColor::Blue => text.bright_blue(), NamedColor::Green => text.bright_green(), - NamedColor::Aqua => text.cyan(), - NamedColor::Red => text.red(), + NamedColor::Aqua => text.bright_cyan(), + NamedColor::Red => text.bright_red(), NamedColor::LightPurple => text.bright_purple(), NamedColor::Yellow => text.bright_yellow(), NamedColor::White => text.white(), }, // TODO: Check if terminal supports true color - Color::Rgb(color) => text.truecolor(color.red, color.green, color.blue), + Self::Rgb(color) => text.truecolor(color.red, color.green, color.blue), } } } @@ -100,8 +102,9 @@ pub struct RGBColor { } impl RGBColor { + #[must_use] pub fn new(red: u8, green: u8, blue: u8) -> Self { - RGBColor { red, green, blue } + Self { red, green, blue } } } @@ -123,8 +126,9 @@ pub struct ARGBColor { } impl ARGBColor { + #[must_use] pub fn new(alpha: u8, red: u8, green: u8, blue: u8) -> Self { - ARGBColor { + Self { alpha, red, green, @@ -162,24 +166,25 @@ pub enum NamedColor { } impl NamedColor { + #[must_use] pub fn to_rgb(&self) -> RGBColor { match self { - NamedColor::Black => RGBColor::new(0, 0, 0), - NamedColor::DarkBlue => RGBColor::new(0, 0, 170), - NamedColor::DarkGreen => RGBColor::new(0, 170, 0), - NamedColor::DarkAqua => RGBColor::new(0, 170, 170), - NamedColor::DarkRed => RGBColor::new(170, 0, 0), - NamedColor::DarkPurple => RGBColor::new(170, 0, 170), - NamedColor::Gold => RGBColor::new(255, 170, 0), - NamedColor::Gray => RGBColor::new(170, 170, 170), - NamedColor::DarkGray => RGBColor::new(85, 85, 85), - NamedColor::Blue => RGBColor::new(85, 85, 255), - NamedColor::Green => RGBColor::new(85, 255, 85), - NamedColor::Aqua => RGBColor::new(85, 255, 255), - NamedColor::Red => RGBColor::new(255, 85, 85), - NamedColor::LightPurple => RGBColor::new(255, 85, 255), - NamedColor::Yellow => RGBColor::new(255, 255, 85), - NamedColor::White => RGBColor::new(255, 255, 255), + Self::Black => RGBColor::new(0, 0, 0), + Self::DarkBlue => RGBColor::new(0, 0, 170), + Self::DarkGreen => RGBColor::new(0, 170, 0), + Self::DarkAqua => RGBColor::new(0, 170, 170), + Self::DarkRed => RGBColor::new(170, 0, 0), + Self::DarkPurple => RGBColor::new(170, 0, 170), + Self::Gold => RGBColor::new(255, 170, 0), + Self::Gray => RGBColor::new(170, 170, 170), + Self::DarkGray => RGBColor::new(85, 85, 85), + Self::Blue => RGBColor::new(85, 85, 255), + Self::Green => RGBColor::new(85, 255, 85), + Self::Aqua => RGBColor::new(85, 255, 255), + Self::Red => RGBColor::new(255, 85, 85), + Self::LightPurple => RGBColor::new(255, 85, 255), + Self::Yellow => RGBColor::new(255, 255, 85), + Self::White => RGBColor::new(255, 255, 255), } } } @@ -189,22 +194,22 @@ impl TryFrom<&str> for NamedColor { fn try_from(value: &str) -> Result { match value { - "black" => Ok(NamedColor::Black), - "dark_blue" => Ok(NamedColor::DarkBlue), - "dark_green" => Ok(NamedColor::DarkGreen), - "dark_aqua" => Ok(NamedColor::DarkAqua), - "dark_red" => Ok(NamedColor::DarkRed), - "dark_purple" => Ok(NamedColor::DarkPurple), - "gold" => Ok(NamedColor::Gold), - "gray" => Ok(NamedColor::Gray), - "dark_gray" => Ok(NamedColor::DarkGray), - "blue" => Ok(NamedColor::Blue), - "green" => Ok(NamedColor::Green), - "aqua" => Ok(NamedColor::Aqua), - "red" => Ok(NamedColor::Red), - "light_purple" => Ok(NamedColor::LightPurple), - "yellow" => Ok(NamedColor::Yellow), - "white" => Ok(NamedColor::White), + "black" => Ok(Self::Black), + "dark_blue" => Ok(Self::DarkBlue), + "dark_green" => Ok(Self::DarkGreen), + "dark_aqua" => Ok(Self::DarkAqua), + "dark_red" => Ok(Self::DarkRed), + "dark_purple" => Ok(Self::DarkPurple), + "gold" => Ok(Self::Gold), + "gray" => Ok(Self::Gray), + "dark_gray" => Ok(Self::DarkGray), + "blue" => Ok(Self::Blue), + "green" => Ok(Self::Green), + "aqua" => Ok(Self::Aqua), + "red" => Ok(Self::Red), + "light_purple" => Ok(Self::LightPurple), + "yellow" => Ok(Self::Yellow), + "white" => Ok(Self::White), _ => Err(()), } } diff --git a/pumpkin-util/src/text/hover.rs b/pumpkin-util/src/text/hover.rs index 10fcfc7d6..6da32427c 100644 --- a/pumpkin-util/src/text/hover.rs +++ b/pumpkin-util/src/text/hover.rs @@ -24,7 +24,7 @@ pub enum HoverEvent { /// The entity's ID Entity Type id: Cow<'static, str>, /// The entity's UUID - /// The UUID cannot use uuid::Uuid because its serialization parses it into bytes, so its double bytes serialized + /// The UUID cannot use `uuid::Uuid` because its serialization parses it into bytes, so its double bytes serialized uuid: Cow<'static, str>, /// Optional custom name for the entity #[serde(default, skip_serializing_if = "Option::is_none")] @@ -33,6 +33,7 @@ pub enum HoverEvent { } impl HoverEvent { + #[must_use] pub fn show_text(text: TextComponent) -> Self { Self::ShowText { value: vec![text.0], diff --git a/pumpkin-util/src/text/mod.rs b/pumpkin-util/src/text/mod.rs index 213bffb25..e30c402b3 100644 --- a/pumpkin-util/src/text/mod.rs +++ b/pumpkin-util/src/text/mod.rs @@ -38,7 +38,7 @@ impl<'de> Deserialize<'de> for TextComponent { content: TextContent::Text { text: Cow::from(v.to_string()), }, - style: Default::default(), + style: Box::default(), extra: vec![], }) } @@ -51,7 +51,7 @@ impl<'de> Deserialize<'de> for TextComponent { Ok(TextComponentBase { content: TextContent::Text { text: "".into() }, - style: Default::default(), + style: Box::default(), extra: bases, }) } @@ -79,16 +79,15 @@ pub struct TextComponentBase { /// The actual text #[serde(flatten)] pub content: TextContent, - /// Style of the text. Bold, Italic, underline, Color... - /// Also has `ClickEvent #[serde(flatten)] pub style: Box