use super::Writer;
use crate::{Entry, Error, LinkId, Result, Storage};
pub struct LazyWriter<T: Entry> {
state: State<T>,
}
#[expect(clippy::large_enum_variant)]
enum State<T: Entry> {
Uncreated {
previous: Option<LinkId>,
storage: Storage,
snapshot: bool,
},
Created {
writer: Writer<T>,
},
}
impl<T: Entry> LazyWriter<T> {
pub fn create(previous: Option<LinkId>, storage: Storage) -> Self {
let state = State::Uncreated {
previous,
storage,
snapshot: false,
};
Self { state }
}
pub fn with_snapshot(&mut self) -> Result<()> {
match &mut self.state {
State::Uncreated { snapshot, .. } => {
*snapshot = true;
Ok(())
}
State::Created { .. } => Err(Error::NotEmpty),
}
}
#[inline]
pub async fn write_unique(&mut self, entry: T) -> Result<u32> {
let writer = self.state.make_created().await?;
writer.write_unique(entry).await
}
}
impl<T: Entry> State<T> {
async fn make_created(&mut self) -> Result<&mut Writer<T>> {
if let Self::Uncreated {
previous,
storage,
snapshot,
} = self
{
let mut writer = Writer::create(*previous, storage.clone()).await?;
if *snapshot {
writer.with_snapshot().await?;
}
*self = Self::Created { writer };
}
let Self::Created { writer } = self else {
unreachable!()
};
Ok(writer)
}
}