diff options
| author | urisinger <60300761+urisinger@users.noreply.github.com> | 2025-09-15 07:51:50 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-14 23:51:50 -0500 |
| commit | bcefd0213db05b4c29c82a1031f4d6e838e1fc1f (patch) | |
| tree | 563797281982fbcced3491e8b3096448903fddc9 /azalea-block/src/lib.rs | |
| parent | 3a58a39563a596e3b08ad41e93070c84e205bddb (diff) | |
| download | azalea-drasl-bcefd0213db05b4c29c82a1031f4d6e838e1fc1f.tar.xz | |
Add functions for getting block properties as strings (#240)
* add tests and fix
* fix integer properties
* refactor azalea-block-macros and improve apis
---------
Co-authored-by: mat <git@matdoes.dev>
Diffstat (limited to 'azalea-block/src/lib.rs')
| -rw-r--r-- | azalea-block/src/lib.rs | 82 |
1 files changed, 75 insertions, 7 deletions
diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs index ead63bef..aa6d5dba 100644 --- a/azalea-block/src/lib.rs +++ b/azalea-block/src/lib.rs @@ -7,7 +7,7 @@ mod generated; mod range; use core::fmt::Debug; -use std::any::Any; +use std::{any::Any, collections::HashMap}; pub use behavior::BlockBehavior; // re-exported for convenience @@ -17,16 +17,34 @@ pub use range::BlockStates; pub trait BlockTrait: Debug + Any { fn behavior(&self) -> BlockBehavior; - /// Get the Minecraft ID for this block. For example `stone` or - /// `grass_block`. + /// Get the Minecraft string ID for this block. + /// + /// For example, `stone` or `grass_block`. fn id(&self) -> &'static str; - /// Convert the block to a block state. This is lossless, as the block - /// contains all the state data. + /// Convert the block to a block state. + /// + /// This is a lossless conversion, as [`BlockState`] also contains state + /// data. fn as_block_state(&self) -> BlockState; - /// Convert the block to an [`azalea_registry::Block`]. This is lossy, as - /// `azalea_registry::Block` doesn't contain any state data. + /// Convert the block to an [`azalea_registry::Block`]. + /// + /// This is a lossy conversion, as [`azalea_registry::Block`] doesn't + /// contain any state data. fn as_registry_block(&self) -> azalea_registry::Block; + + /// Returns a map of property names on this block to their values as + /// strings. + /// + /// Consider using [`Self::get_property`] if you only need a single + /// property. + fn property_map(&self) -> HashMap<&'static str, &'static str>; + /// Get a property's value as a string by its name, or `None` if the block + /// has no property with that name. + /// + /// To get all properties, you may use [`Self::property_map`]. + fn get_property(&self, name: &str) -> Option<&'static str>; } + impl dyn BlockTrait { pub fn downcast_ref<T: BlockTrait>(&self) -> Option<&T> { (self as &dyn Any).downcast_ref::<T>() @@ -37,6 +55,9 @@ pub trait Property { type Value; fn try_from_block_state(state: BlockState) -> Option<Self::Value>; + + /// Convert the value of the property to a string, like "x" or "true". + fn to_static_str(&self) -> &'static str; } #[cfg(test)] @@ -60,4 +81,51 @@ mod tests { .clone(); assert_eq!(block, block_from_state); } + + #[test] + pub fn test_property_map() { + let block = crate::blocks::OakTrapdoor { + facing: crate::properties::FacingCardinal::East, + half: crate::properties::TopBottom::Bottom, + open: true, + powered: false, + waterlogged: false, + }; + + let property_map = block.property_map(); + + assert_eq!(property_map.len(), 5); + assert_eq!(property_map.get("facing"), Some(&"east")); + assert_eq!(property_map.get("half"), Some(&"bottom")); + assert_eq!(property_map.get("open"), Some(&"true")); + assert_eq!(property_map.get("powered"), Some(&"false")); + assert_eq!(property_map.get("waterlogged"), Some(&"false")); + } + + #[test] + pub fn test_integer_properties() { + // Test with oak sapling that has an integer-like stage property + let sapling_stage_0 = crate::blocks::OakSapling { + stage: crate::properties::OakSaplingStage::_0, + }; + + let sapling_stage_1 = crate::blocks::OakSapling { + stage: crate::properties::OakSaplingStage::_1, + }; + + // Test stage 0 + let properties_0 = sapling_stage_0.property_map(); + assert_eq!(properties_0.len(), 1); + assert_eq!(properties_0.get("stage"), Some(&"0")); + assert_eq!(sapling_stage_0.get_property("stage"), Some("0")); + + // Test stage 1 + let properties_1 = sapling_stage_1.property_map(); + assert_eq!(properties_1.len(), 1); + assert_eq!(properties_1.get("stage"), Some(&"1")); + assert_eq!(sapling_stage_1.get_property("stage"), Some("1")); + + // Test non-existent property + assert_eq!(sapling_stage_0.get_property("nonexistent"), None); + } } |
