use std::fs::File;
use std::path::Path;
use tempfile::NamedTempFile;
use crate::error::{Error, FileOperation};
pub(crate) struct Staged {
temp: NamedTempFile,
}
impl Staged {
pub fn beside(target: &Path) -> Result<Self, Error> {
let dir = target.parent().filter(|p| !p.as_os_str().is_empty()).unwrap_or(Path::new("."));
let temp = tempfile::Builder::new()
.prefix(".apk-rs-")
.suffix(".tmp")
.tempfile_in(dir)
.map_err(Error::file(FileOperation::Create, dir))?;
Ok(Self { temp })
}
pub fn file(&mut self) -> &mut File {
self.temp.as_file_mut()
}
pub fn path(&self) -> &Path {
self.temp.path()
}
pub fn persist(self, target: &Path) -> Result<(), Error> {
let file = self.temp.as_file();
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
file.set_permissions(std::fs::Permissions::from_mode(0o644))
.map_err(Error::file(FileOperation::Write, self.temp.path()))?;
}
file.sync_all().map_err(Error::file(FileOperation::Write, self.temp.path()))?;
self.temp.persist(target).map_err(|error| Error::File {
operation: FileOperation::Persist,
path: target.to_owned(),
source: error.error,
})?;
Ok(())
}
}