use std::fmt;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[must_use]
pub struct FieldHandle {
pub(crate) generation: u32,
pub(crate) offset: u32,
pub(crate) len: u32,
pub(crate) location: FieldLocation,
}
impl FieldHandle {
pub(crate) fn new(generation: u32, offset: u32, len: u32, location: FieldLocation) -> Self {
Self {
generation,
offset,
len,
location,
}
}
pub fn generation(&self) -> u32 {
self.generation
}
pub fn len(&self) -> u32 {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn location(&self) -> FieldLocation {
self.location
}
}
impl fmt::Display for FieldHandle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"FieldHandle(gen={}, off={}, len={}, {:?})",
self.generation, self.offset, self.len, self.location
)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FieldLocation {
PerTick {
segment_index: u16,
},
Sparse {
segment_index: u16,
},
Static {
offset: u32,
len: u32,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn handle_round_trip() {
let loc = FieldLocation::PerTick { segment_index: 3 };
let h = FieldHandle::new(42, 1024, 256, loc);
assert_eq!(h.generation(), 42);
assert_eq!(h.len(), 256);
assert!(!h.is_empty());
assert_eq!(h.location(), loc);
}
#[test]
fn empty_handle() {
let h = FieldHandle::new(0, 0, 0, FieldLocation::PerTick { segment_index: 0 });
assert!(h.is_empty());
}
#[test]
fn static_location_stores_offset_and_len() {
let loc = FieldLocation::Static {
offset: 100,
len: 50,
};
if let FieldLocation::Static { offset, len } = loc {
assert_eq!(offset, 100);
assert_eq!(len, 50);
} else {
panic!("expected Static");
}
}
}