use crate::{
Error, LinkId, Result,
storage::{self, Reader, Writer},
};
pub struct Footer {
pub previous: Option<LinkId>,
pub index: u32,
pub count: u32,
}
impl Footer {
pub const SIZE: usize = 26;
pub async fn read(reader: &mut Reader) -> Result<Self> {
if reader.file_size() < Self::SIZE {
return Err(Error::FileSize {
expected: Self::SIZE,
got: reader.file_size(),
});
}
reader.goto(-2)?;
let version = reader.read_u16().await?;
if version != storage::VERSION {
return Err(Error::Version {
expected: storage::VERSION,
got: version,
});
}
reader.goto(-(Self::SIZE as isize))?;
let previous = reader.read_u128().await?;
let previous = if previous == 0 {
None
} else {
Some(LinkId::from_u128(previous))
};
let index = reader.read_u32().await?;
let count = reader.read_u32().await?;
let end = reader.file_size() - Self::SIZE;
reader.set_file_size(end);
Ok(Self {
previous,
index,
count,
})
}
pub async fn write(&self, writer: &mut Writer) -> Result<()> {
let Self {
previous,
index,
count,
} = self;
let previous = previous.as_ref().map(LinkId::as_u128).unwrap_or_default();
writer.write_u128(previous).await?;
writer.write_u32(*index).await?;
writer.write_u32(*count).await?;
writer.write_u16(storage::VERSION).await?;
Ok(())
}
}