use core::fmt::Debug;
pub type SegmentIdUnderlyingType = u8;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SegmentId(SegmentIdUnderlyingType);
impl SegmentId {
pub const fn new(value: SegmentIdUnderlyingType) -> Self {
Self(value)
}
pub const fn value(&self) -> SegmentIdUnderlyingType {
self.0
}
pub const fn max_segment_id() -> SegmentIdUnderlyingType {
SegmentIdUnderlyingType::MAX
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct PointerOffset(u64);
impl PointerOffset {
pub const fn new(offset: usize) -> PointerOffset {
const SEGMENT_ID: u8 = 0;
Self::from_offset_and_segment_id(offset, SegmentId::new(SEGMENT_ID))
}
pub const fn from_offset_and_segment_id(offset: usize, segment_id: SegmentId) -> PointerOffset {
Self(((offset as u64) << (SegmentIdUnderlyingType::BITS)) | segment_id.value() as u64)
}
pub const fn from_value(value: u64) -> PointerOffset {
Self(value)
}
pub const fn as_value(&self) -> u64 {
self.0
}
pub fn set_segment_id(&mut self, value: SegmentId) {
self.0 &= !((1u64 << SegmentIdUnderlyingType::BITS) - 1);
self.0 |= value.0 as u64;
}
pub const fn offset(&self) -> usize {
(self.0 >> (SegmentIdUnderlyingType::BITS)) as usize
}
pub const fn segment_id(&self) -> SegmentId {
SegmentId((self.0 & ((1u64 << SegmentIdUnderlyingType::BITS) - 1)) as u8)
}
}
impl Debug for PointerOffset {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"PointerOffset {{ offset: {}, segment_id: {:?} }}",
self.offset(),
self.segment_id()
)
}
}