use std::fmt::Display;
use bitfield::bitfield;
bitfield! {
#[repr(C)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct BlockId(i32);
impl Debug;
u8;
pub area, _: 31, 24;
_, set_area: 31, 24;
pub block, _: 23, 16;
_, set_block: 23, 16;
pub region, _: 15, 8;
_, set_region: 15, 8;
pub index, _: 7, 0;
_, set_index: 7, 0;
}
impl BlockId {
pub const fn none() -> Self {
Self(-1)
}
pub fn from_parts(area: u8, block: u8, region: u8, index: u8) -> Self {
let mut blockid = BlockId(0);
blockid.set_area(area);
blockid.set_block(block);
blockid.set_region(region);
blockid.set_index(index);
blockid
}
pub fn is_overworld(&self) -> bool {
let area = self.area();
(50..89).contains(&area)
}
}
impl From<BlockId> for i32 {
fn from(val: BlockId) -> Self {
val.0
}
}
impl From<i32> for BlockId {
fn from(value: i32) -> Self {
Self(value)
}
}
impl Display for BlockId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"m{:0>2}_{:0>2}_{:0>2}_{:0>2}",
self.area(),
self.block(),
self.region(),
self.index()
)
}
}
#[cfg(test)]
mod tests {
use crate::cs::BlockId;
#[test]
fn test_bitfield() {
let mut blockid = BlockId(0);
blockid.set_area(61);
blockid.set_block(57);
blockid.set_region(39);
blockid.set_index(3);
assert_eq!(blockid.area(), 61);
assert_eq!(blockid.block(), 57);
assert_eq!(blockid.region(), 39);
assert_eq!(blockid.index(), 3);
assert_eq!(blockid.0, 0x3D392703);
}
}