use alloc::vec::Vec;
pub trait Storage {
type Error: core::fmt::Debug;
fn read_snapshot(&mut self) -> Result<Option<Vec<u8>>, Self::Error>;
fn write_snapshot(&mut self, bytes: &[u8]) -> Result<(), Self::Error>;
fn read_journal(&mut self) -> Result<Vec<u8>, Self::Error>;
fn append_journal(&mut self, entry: &[u8]) -> Result<(), Self::Error>;
fn clear_journal(&mut self) -> Result<(), Self::Error>;
}
pub trait Scratch {
type Error: core::fmt::Debug;
fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error>;
fn len(&self) -> u64;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn freeze(&mut self) -> Result<&[u8], Self::Error>;
}
#[derive(Debug, Default, Clone)]
pub struct MemScratch {
buf: Vec<u8>,
}
impl MemScratch {
pub fn new() -> Self {
Self::default()
}
}
impl Scratch for MemScratch {
type Error = core::convert::Infallible;
fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
self.buf.extend_from_slice(bytes);
Ok(())
}
fn len(&self) -> u64 {
self.buf.len() as u64
}
fn freeze(&mut self) -> Result<&[u8], Self::Error> {
Ok(&self.buf)
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct MemStorage {
snapshot: Option<Vec<u8>>,
journal: Vec<u8>,
}
impl MemStorage {
pub fn new() -> Self {
Self::default()
}
}
impl Storage for MemStorage {
type Error = core::convert::Infallible;
fn read_snapshot(&mut self) -> Result<Option<Vec<u8>>, Self::Error> {
Ok(self.snapshot.clone())
}
fn write_snapshot(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
self.snapshot = Some(bytes.to_vec());
Ok(())
}
fn read_journal(&mut self) -> Result<Vec<u8>, Self::Error> {
Ok(self.journal.clone())
}
fn append_journal(&mut self, entry: &[u8]) -> Result<(), Self::Error> {
self.journal.extend_from_slice(entry);
Ok(())
}
fn clear_journal(&mut self) -> Result<(), Self::Error> {
self.journal.clear();
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mem_scratch_builds_and_freezes_to_the_concatenation() {
let mut s = MemScratch::new();
assert!(s.is_empty());
s.write(b"hello ").unwrap();
s.write(b"world").unwrap();
assert_eq!(s.len(), 11);
assert!(!s.is_empty());
assert_eq!(s.freeze().unwrap(), b"hello world");
assert_eq!(&s.freeze().unwrap()[6..], b"world");
}
}