aboutsummaryrefslogtreecommitdiff
path: root/azalea-block/src/lib.rs
diff options
context:
space:
mode:
authorurisinger <60300761+urisinger@users.noreply.github.com>2025-09-15 07:51:50 +0300
committerGitHub <noreply@github.com>2025-09-14 23:51:50 -0500
commitbcefd0213db05b4c29c82a1031f4d6e838e1fc1f (patch)
tree563797281982fbcced3491e8b3096448903fddc9 /azalea-block/src/lib.rs
parent3a58a39563a596e3b08ad41e93070c84e205bddb (diff)
downloadazalea-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.rs82
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);
+ }
}