#[derive(Clone)]
pub struct Block {
pub contents: [u8; Block::LEN],
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct BlockIdx(pub u32);
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct BlockCount(pub u32);
pub struct BlockIter {
inclusive_end: BlockIdx,
current: BlockIdx,
}
pub trait BlockDevice {
type Error: core::fmt::Debug;
fn read(
&self,
blocks: &mut [Block],
start_block_idx: BlockIdx,
reason: &str,
) -> Result<(), Self::Error>;
fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
fn num_blocks(&self) -> Result<BlockCount, Self::Error>;
}
impl Block {
pub const LEN: usize = 512;
pub const LEN_U32: u32 = 512;
pub fn new() -> Block {
Block {
contents: [0u8; Self::LEN],
}
}
}
impl Default for Block {
fn default() -> Self {
Self::new()
}
}
impl core::ops::Add<BlockCount> for BlockIdx {
type Output = BlockIdx;
fn add(self, rhs: BlockCount) -> BlockIdx {
BlockIdx(self.0 + rhs.0)
}
}
impl core::ops::AddAssign<BlockCount> for BlockIdx {
fn add_assign(&mut self, rhs: BlockCount) {
self.0 += rhs.0
}
}
impl core::ops::Add<BlockCount> for BlockCount {
type Output = BlockCount;
fn add(self, rhs: BlockCount) -> BlockCount {
BlockCount(self.0 + rhs.0)
}
}
impl core::ops::AddAssign<BlockCount> for BlockCount {
fn add_assign(&mut self, rhs: BlockCount) {
self.0 += rhs.0
}
}
impl core::ops::Sub<BlockCount> for BlockIdx {
type Output = BlockIdx;
fn sub(self, rhs: BlockCount) -> BlockIdx {
BlockIdx(self.0 - rhs.0)
}
}
impl core::ops::SubAssign<BlockCount> for BlockIdx {
fn sub_assign(&mut self, rhs: BlockCount) {
self.0 -= rhs.0
}
}
impl core::ops::Sub<BlockCount> for BlockCount {
type Output = BlockCount;
fn sub(self, rhs: BlockCount) -> BlockCount {
BlockCount(self.0 - rhs.0)
}
}
impl core::ops::SubAssign<BlockCount> for BlockCount {
fn sub_assign(&mut self, rhs: BlockCount) {
self.0 -= rhs.0
}
}
impl core::ops::Deref for Block {
type Target = [u8; 512];
fn deref(&self) -> &[u8; 512] {
&self.contents
}
}
impl core::ops::DerefMut for Block {
fn deref_mut(&mut self) -> &mut [u8; 512] {
&mut self.contents
}
}
impl core::fmt::Debug for Block {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
writeln!(fmt, "Block:")?;
for line in self.contents.chunks(32) {
for b in line {
write!(fmt, "{:02x}", b)?;
}
write!(fmt, " ")?;
for &b in line {
if b >= 0x20 && b <= 0x7F {
write!(fmt, "{}", b as char)?;
} else {
write!(fmt, ".")?;
}
}
writeln!(fmt)?;
}
Ok(())
}
}
impl BlockIdx {
pub fn into_bytes(self) -> u64 {
(u64::from(self.0)) * (Block::LEN as u64)
}
pub fn range(self, num: BlockCount) -> BlockIter {
BlockIter::new(self, self + BlockCount(num.0 - 1))
}
}
impl BlockCount {
pub fn offset_bytes(self, offset: u32) -> Self {
BlockCount(self.0 + (offset / Block::LEN_U32))
}
}
impl BlockIter {
pub fn new(start: BlockIdx, inclusive_end: BlockIdx) -> BlockIter {
BlockIter {
inclusive_end,
current: start,
}
}
}
impl core::iter::Iterator for BlockIter {
type Item = BlockIdx;
fn next(&mut self) -> Option<Self::Item> {
if self.current.0 >= self.inclusive_end.0 {
None
} else {
let this = self.current;
self.current = self.current + BlockCount(1);
Some(this)
}
}
}