#![doc = include_str!("../README.md")] mod behavior; pub mod block_state; pub mod fluid_state; mod generated; mod range; use core::fmt::Debug; use std::any::Any; pub use behavior::BlockBehavior; // re-exported for convenience pub use block_state::BlockState; pub use generated::{blocks, properties}; 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`. fn id(&self) -> &'static str; /// Convert the block to a block state. This is lossless, as the block /// contains all the 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. fn as_registry_block(&self) -> azalea_registry::Block; } impl dyn BlockTrait { pub fn downcast_ref(&self) -> Option<&T> { (self as &dyn Any).downcast_ref::() } } pub trait Property { type Value; fn try_from_block_state(state: BlockState) -> Option; } #[cfg(test)] mod tests { use crate::BlockTrait; #[test] pub fn roundtrip_block_state() { let block = crate::blocks::OakTrapdoor { facing: crate::properties::FacingCardinal::East, half: crate::properties::TopBottom::Bottom, open: true, powered: false, waterlogged: false, }; let block_state = block.as_block_state(); let block_from_state = Box::::from(block_state); let block_from_state = block_from_state .downcast_ref::() .unwrap() .clone(); assert_eq!(block, block_from_state); } }