use super::{Commit, FileIo, is_pristine, load_snapshot, stage};
#[cfg(test)]
use std::path::Path;
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub(crate) struct Draft {
path: PathBuf,
text: String,
loaded: Option<u64>,
}
impl Draft {
pub(crate) fn load(path: PathBuf, io: &dyn FileIo) -> std::io::Result<Self> {
let (text, loaded) = load_snapshot(io, &path)?;
Ok(Self { path, text, loaded })
}
pub(crate) fn seeded(path: PathBuf, seed: &[u8]) -> Self {
Self {
path,
text: String::from_utf8_lossy(seed).into_owned(),
loaded: None,
}
}
#[cfg(test)]
pub(crate) fn path(&self) -> &Path {
&self.path
}
#[cfg(test)]
pub(crate) fn text(&self) -> &str {
&self.text
}
pub(crate) fn set(&mut self, text: String) {
self.text = text;
}
pub(crate) fn is_new(&self) -> bool {
self.loaded.is_none()
}
pub(crate) fn reload(&mut self, io: &dyn FileIo) -> std::io::Result<()> {
let (text, loaded) = load_snapshot(io, &self.path)?;
self.text = text;
self.loaded = loaded;
Ok(())
}
pub(crate) fn refresh(&mut self, io: &dyn FileIo) -> std::io::Result<bool> {
if !is_pristine(&self.text, self.loaded) {
return Ok(false);
}
self.reload(io)?;
Ok(true)
}
pub(crate) fn stage(&self, io: &dyn FileIo) -> std::io::Result<super::pipeline::Staged> {
stage(io, &self.path, self.text.as_bytes())
}
pub(crate) fn commit(
&mut self,
staged: super::pipeline::Staged,
io: &dyn FileIo,
) -> std::io::Result<bool> {
match staged.commit(io, self.loaded)? {
Commit::Ok(hash) => {
self.loaded = Some(hash);
Ok(true)
}
Commit::Conflict => Ok(false),
}
}
}