use byteorder::{BigEndian, ReadBytesExt};
use bytes::{BufMut, BytesMut};
use std::io::{self, Cursor};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ImmutableFileEntryError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ImmutableFileEntry {
pub file_number: u64,
}
impl ImmutableFileEntry {
pub fn new(file_number: u64) -> Self {
Self { file_number }
}
pub fn log_size(&self) -> usize {
8 }
pub fn write_to_log(&self, buf: &mut BytesMut) {
buf.put_u64(self.file_number);
}
pub fn read_from_log(buf: &[u8]) -> Result<Self, ImmutableFileEntryError> {
let mut cursor = Cursor::new(buf);
let file_number = cursor.read_u64::<BigEndian>()?;
Ok(Self { file_number })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_immutable_file_roundtrip() {
let entry = ImmutableFileEntry::new(42);
let mut buf = BytesMut::new();
entry.write_to_log(&mut buf);
let decoded = ImmutableFileEntry::read_from_log(&buf).unwrap();
assert_eq!(entry, decoded);
assert_eq!(decoded.file_number, 42);
}
#[test]
fn test_immutable_file_zero() {
let entry = ImmutableFileEntry::new(0);
let mut buf = BytesMut::new();
entry.write_to_log(&mut buf);
let decoded = ImmutableFileEntry::read_from_log(&buf).unwrap();
assert_eq!(entry, decoded);
assert_eq!(decoded.file_number, 0);
}
#[test]
fn test_log_size() {
let entry = ImmutableFileEntry::new(1);
assert_eq!(entry.log_size(), 8);
let mut buf = BytesMut::new();
entry.write_to_log(&mut buf);
assert_eq!(buf.len(), entry.log_size());
}
}