Skip to content

Commit

Permalink
zip-or-dir: implement open_raw_or_gz()
Browse files Browse the repository at this point in the history
  • Loading branch information
astraw committed Oct 25, 2023
1 parent 54f2ec8 commit 7a4725d
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ test_crates_rust_1_72:

# Test zip-or-dir
- cd zip-or-dir
- cargo test
- cargo test --features with-gz
- cd ..

# Test fastfreeimage
Expand Down
8 changes: 2 additions & 6 deletions braid-offline/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
#![cfg_attr(
feature = "backtrace",
feature(error_generic_member_access)
)]
#![cfg_attr(feature = "backtrace", feature(error_generic_member_access))]

use std::{
collections::BTreeMap,
Expand Down Expand Up @@ -702,8 +699,7 @@ fn open_buffered<P: AsRef<Path>>(p: &P) -> std::io::Result<std::io::BufReader<Fi
/// This should not be used in the general case but only for special cases where
/// a raw directory is being used, such as specifically when modifying a
/// directory under construction. For the general reading case, prefer
/// `braidz_parser` crate (or the `zip_or_dir` if it may not be a valid braidz
/// archive) crate.
/// [zip_or_dir::ZipDirArchive::open_raw_or_gz].
pub fn pick_csvgz_or_csv(csv_path: &Path) -> flydra2::Result<Box<dyn Read>> {
let gz_fname = PathBuf::from(csv_path).with_extension("csv.gz");

Expand Down
2 changes: 2 additions & 0 deletions zip-or-dir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ categories = [ "compression", "filesystem" ]
[dependencies]
zip = { version = "0.6.2", default-features = false, features=["deflate", "time"] }
thiserror = "1.0.33"
libflate = {version = "1.2.0", optional = true}

[dev-dependencies]
tempfile = "3.4"

[features]
backtrace = []
with-gz = ["libflate"]
48 changes: 44 additions & 4 deletions zip-or-dir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
// or http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

#![cfg_attr(
feature = "backtrace",
feature(error_generic_member_access)
)]
#![cfg_attr(feature = "backtrace", feature(error_generic_member_access))]

//! An archive of "files", either in a filesystem directory or zip archive.
//!
Expand Down Expand Up @@ -319,6 +316,40 @@ impl<R: Read + Seek> ZipDirArchive<R> {
}
Ok(result)
}

/// Open raw file (e.g. `.csv`) or gz version (e.g. `.csv.gz`) of a file.
///
/// This prefers to use the gz compressed file if it exists.
#[cfg(feature = "with-gz")]
pub fn open_raw_or_gz(&mut self, src_fname: &str) -> Result<MaybeGzReader> {
let gz_fname = format!("{}.gz", src_fname);
let gz_exists = self.path_starter().join(&gz_fname).exists();

if gz_exists {
let gz_fd = self.path_starter().join(gz_fname).open()?;
let decoder = libflate::gzip::Decoder::new(gz_fd)?;
Ok(MaybeGzReader::Gz(decoder))
} else {
let fd = self.path_starter().join(src_fname).open()?;
Ok(MaybeGzReader::Raw(fd))
}
}
}

#[cfg(feature = "with-gz")]
pub enum MaybeGzReader<'a> {
Raw(FileReader<'a>),
Gz(libflate::gzip::Decoder<FileReader<'a>>),
}

#[cfg(feature = "with-gz")]
impl<'a> Read for MaybeGzReader<'a> {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
match self {
Self::Raw(fd) => fd.read(buf),
Self::Gz(gz_fd) => gz_fd.read(buf),
}
}
}

/// Provides a single concrete type for a normal file or a zipped file.
Expand Down Expand Up @@ -771,6 +802,15 @@ mod tests {
}
}

#[cfg(feature = "with-gz")]
{
let mut buf = String::new();
archive
.open_raw_or_gz("subdir2/8")?
.read_to_string(&mut buf)?;
assert_eq!(&buf, "8");
}

Ok(())
}
}

0 comments on commit 7a4725d

Please sign in to comment.