aboutsummaryrefslogtreecommitdiff
path: root/azalea-block/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'azalea-block/src/lib.rs')
-rw-r--r--azalea-block/src/lib.rs41
1 files changed, 41 insertions, 0 deletions
diff --git a/azalea-block/src/lib.rs b/azalea-block/src/lib.rs
index 01c86b11..95e8ce37 100644
--- a/azalea-block/src/lib.rs
+++ b/azalea-block/src/lib.rs
@@ -4,3 +4,44 @@ mod blocks;
pub use behavior::BlockBehavior;
pub use blocks::*;
+use std::mem;
+
+impl BlockState {
+ /// Transmutes a u32 to a block state. UB if the value is not a valid block
+ /// state.
+ #[inline]
+ pub unsafe fn from_u32_unsafe(state_id: u32) -> Self {
+ mem::transmute::<u32, BlockState>(state_id)
+ }
+
+ #[inline]
+ pub fn is_valid_state(state_id: u32) -> bool {
+ state_id <= Self::max_state()
+ }
+}
+
+impl TryFrom<u32> for BlockState {
+ type Error = ();
+
+ /// Safely converts a state id to a block state.
+ fn try_from(state_id: u32) -> Result<Self, Self::Error> {
+ if Self::is_valid_state(state_id) {
+ Ok(unsafe { Self::from_u32_unsafe(state_id) })
+ } else {
+ Err(())
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_from_u32() {
+ assert_eq!(BlockState::try_from(0).unwrap(), BlockState::Air);
+
+ assert!(BlockState::try_from(BlockState::max_state()).is_ok());
+ assert!(BlockState::try_from(BlockState::max_state() + 1).is_err());
+ }
+}