Skip to content

Commit

Permalink
rust: Remove file properties from EKO
Browse files Browse the repository at this point in the history
  • Loading branch information
felixhekhorn committed Aug 20, 2024
1 parent 1a696a1 commit 8d0d759
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 73 deletions.
70 changes: 10 additions & 60 deletions crates/dekoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ pub enum EKOError {
NoWorkingDir,
#[error("I/O error")]
IOError(#[from] std::io::Error),
#[error("No target path given")]
NoTargetPath,
#[error("Target path `{0}` already exists")]
TargetAlreadyExists(PathBuf),
#[error("Loading operator from `{0}` failed")]
OperatorLoadError(PathBuf),
#[error("Failed to read key(s) `{0}`")]
Expand Down Expand Up @@ -96,10 +92,6 @@ impl Eq for EvolutionPoint {}
pub struct EKO {
/// Working directory
path: PathBuf,
/// Associated archive path
tar_path: Option<PathBuf>,
/// allow content modifications?
read_only: bool,
/// final operators
operators: inventory::Inventory<EvolutionPoint>,
}
Expand All @@ -118,87 +110,45 @@ impl EKO {
}

/// Remove the working directory.
fn destroy(&self) -> Result<()> {
pub fn destroy(&self) -> Result<()> {
self.check()?;
Ok(remove_dir_all(&self.path)?)
}

/// Write content back to an archive and destroy working directory.
pub fn close(&self) -> Result<()> {
self.write(false, true)
}

/// Write content back to an archive and destroy working directory.
pub fn overwrite_and_close(&self) -> Result<()> {
self.write(true, true)
pub fn write_and_destroy(&self, dst: PathBuf) -> Result<()> {
self.write(dst)?;
self.destroy()?;
Ok(())
}

/// Write content back to an archive.
pub fn write(&self, allow_overwrite: bool, destroy: bool) -> Result<()> {
pub fn write(&self, dst: PathBuf) -> Result<()> {
self.check()?;
// in read-only there is nothing to do then to destroy, since we couldn't
if self.read_only && destroy {
return self.destroy();
}
// check we can write
if self.tar_path.is_none() {
return Err(EKOError::NoTargetPath);
}
let dst = self.tar_path.to_owned().ok_or(EKOError::NoTargetPath)?;
let dst_exists = dst.try_exists().is_ok_and(|x| x);
if !allow_overwrite && dst_exists {
return Err(EKOError::TargetAlreadyExists(dst));
}
// create writer
let dst_file = File::create(&dst)?;
let dst_file = BufWriter::with_capacity(128 * 1024, dst_file);
let mut ar = tar::Builder::new(dst_file);
// do it!
ar.append_dir_all(".", &self.path)?;
// cleanup
if destroy {
self.destroy()?;
}
Ok(())
}

/// Set the archive path.
pub fn set_tar_path(&mut self, tar_path: PathBuf) {
self.tar_path = Some(tar_path.to_owned());
}

/// Open tar from `src` to `dst` for reading.
pub fn read(src: PathBuf, dst: PathBuf) -> Result<Self> {
Self::extract(src, dst, true)
}

/// Open tar from `src` to `dst` for editing.
pub fn edit(src: PathBuf, dst: PathBuf) -> Result<Self> {
Self::extract(src, dst, false)
}

/// Extract tar file from `src` to `dst`.
pub fn extract(src: PathBuf, dst: PathBuf, read_only: bool) -> Result<Self> {
pub fn extract(src: PathBuf, dst: PathBuf) -> Result<Self> {
let mut ar = tar::Archive::new(File::open(&src)?);
ar.unpack(&dst)?;
let mut obj = Self::load_opened(dst, read_only)?;
obj.set_tar_path(src);
Ok(obj)
Self::load_opened(dst)
}

/// Load an EKO from a directory `path` (instead of tar).
pub fn load_opened(path: PathBuf, read_only: bool) -> Result<Self> {
pub fn load_opened(path: PathBuf) -> Result<Self> {
let mut operators = inventory::Inventory {
path: path.join(DIR_OPERATORS),
keys: HashMap::new(),
};
operators.load_keys()?;
let obj = Self {
path,
tar_path: None,
read_only,
operators,
};
let obj = Self { path, operators };
obj.check()?;
Ok(obj)
}
Expand Down
25 changes: 12 additions & 13 deletions crates/dekoder/tests/test_load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use std::path::PathBuf;

use dekoder::{EvolutionPoint, Operator, EKO};

// assert_fs will clean up the directories for us,
// so for the most part we don't need worry about that.

/// Get v0.15 test object.
fn v015tar() -> PathBuf {
let base: PathBuf = [env!("CARGO_MANIFEST_DIR"), "tests"].iter().collect();
Expand All @@ -17,20 +20,19 @@ fn open() {
let src = v015tar();
let dst = assert_fs::TempDir::new().unwrap();
// open
let eko = EKO::read(src.to_owned(), dst.to_owned()).unwrap();
let _eko = EKO::extract(src.to_owned(), dst.to_owned()).unwrap();
let metadata = dst.child("metadata.yaml");
metadata.assert(predicate::path::exists());
eko.close().unwrap();
}

#[test]
fn close() {
fn destroy() {
let src = v015tar();
let dst = assert_fs::TempDir::new().unwrap();
{
// open + close
let eko = EKO::read(src.to_owned(), dst.to_owned()).unwrap();
eko.close().unwrap();
// extract + destroy
let eko = EKO::extract(src.to_owned(), dst.to_owned()).unwrap();
eko.destroy().unwrap();
}
dst.assert(predicate::path::missing());
}
Expand All @@ -40,11 +42,10 @@ fn save_as_other() {
let src = v015tar();
let dst = assert_fs::TempDir::new().unwrap();
// open
let mut eko = EKO::edit(src.to_owned(), dst.to_owned()).unwrap();
let eko = EKO::extract(src.to_owned(), dst.to_owned()).unwrap();
// write to somewhere else
let tarb = assert_fs::NamedTempFile::new("v0.15b.tar").unwrap();
eko.set_tar_path(tarb.to_owned());
eko.overwrite_and_close().unwrap();
eko.write(tarb.to_owned()).unwrap();
tarb.assert(predicate::path::exists());
}

Expand All @@ -53,7 +54,7 @@ fn has_operator() {
let src = v015tar();
let dst = assert_fs::TempDir::new().unwrap();
// open
let eko = EKO::read(src.to_owned(), dst.to_owned()).unwrap();
let eko = EKO::extract(src.to_owned(), dst.to_owned()).unwrap();
// check there is only one:
assert!(eko.available_operators().len() == 1);
// ask for one
Expand All @@ -64,15 +65,14 @@ fn has_operator() {
// it is the one
assert!(ep.eq(eko.available_operators()[0]));
assert!(eko.has_operator(&ep));
eko.close().unwrap();
}

#[test]
fn load_operator() {
let src = v015tar();
let dst = assert_fs::TempDir::new().unwrap();
// open
let eko = EKO::read(src.to_owned(), dst.to_owned()).unwrap();
let eko = EKO::extract(src.to_owned(), dst.to_owned()).unwrap();
// load
let ep = EvolutionPoint {
scale: 10000.,
Expand All @@ -82,5 +82,4 @@ fn load_operator() {
eko.load_operator(&ep, &mut op).unwrap();
assert!(op.op.is_some());
assert!(op.op.unwrap().dim().0 > 0);
eko.close().unwrap();
}

0 comments on commit 8d0d759

Please sign in to comment.