Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion workspace/compress/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "compress"
name = "substratum-compress"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
Expand Down
10 changes: 10 additions & 0 deletions workspace/compress/src/decode/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::decode::{
DecodeBufReadIntoBufRead, DecodeBufReadIntoRead, DecodeReadIntoBufRead, DecodeReadIntoRead,
};
use std::io::{BufRead, Error, Read};
use std::path::Path;

#[cfg_attr(feature = "bitcode", derive(::bitcode::Encode, ::bitcode::Decode))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down Expand Up @@ -74,3 +75,12 @@ impl_decompression_trait!(
DecodeBufReadIntoBufRead,
decode_bufread_into_bufread
);

impl Decoder {
pub fn from_extension(ext: &str, uncompressed_exts: &[&str]) -> std::io::Result<Self> {
crate::Format::from_extension(ext, uncompressed_exts).map(|x| x.decoder())
}
pub fn from_path(path: impl AsRef<Path>, uncompressed_exts: &[&str]) -> std::io::Result<Self> {
crate::Format::from_path(path, uncompressed_exts).map(|x| x.decoder())
}
}
10 changes: 10 additions & 0 deletions workspace/compress/src/encode/encoder.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::adapter::Adapter;
use super::encode::Encode;
use std::io::{Error, Write};
use std::path::Path;

#[cfg_attr(feature = "bitcode", derive(::bitcode::Encode, ::bitcode::Decode))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down Expand Up @@ -48,3 +49,12 @@ where
}
}
}

impl Encoder {
pub fn from_extension(ext: &str, uncompressed_exts: &[&str]) -> std::io::Result<Self> {
crate::Format::from_extension(ext, uncompressed_exts).map(|x| x.encoder())
}
pub fn from_path(path: impl AsRef<Path>, uncompressed_exts: &[&str]) -> std::io::Result<Self> {
crate::Format::from_path(path, uncompressed_exts).map(|x| x.encoder())
}
}
45 changes: 28 additions & 17 deletions workspace/compress/src/format.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{decode, encode};
use std::io::{Error, ErrorKind, Result};
use std::path::Path;

const DEFLATE: &[&str] = &[];
Expand All @@ -18,32 +19,42 @@ pub enum Format {
}

impl Format {
pub fn from_extension(ext: &str, uncompressed_exts: &[&str]) -> Option<Self> {
pub fn from_extension(ext: &str, uncompressed_exts: &[&str]) -> Result<Self> {
match ext {
// Empty extension can't be used to infer format
ext if ext.is_empty() => None,
ext if ext.is_empty() => Err(Error::new(
ErrorKind::InvalidInput,
"Can't infer format from empty extension",
)),

// Uncompressed files
ext if uncompressed_exts.contains(&ext) => Some(Self::Uncompressed),
ext if uncompressed_exts.contains(&ext) => Ok(Self::Uncompressed),

// DEFLATE compressed files
#[cfg(any(feature = "decode-deflate", feature = "encode-deflate"))]
ext if DEFLATE.contains(&ext) => Some(Self::Deflate),
ext if DEFLATE.contains(&ext) => Ok(Self::Deflate),

// GZIP compressed files
#[cfg(any(feature = "decode-gzip", feature = "encode-gzip"))]
ext if GZIP.contains(&ext) => Some(Self::Gzip),
ext if GZIP.contains(&ext) => Ok(Self::Gzip),

// BGZF compressed files
#[cfg(any(feature = "decode-bgzf", feature = "encode-bgzf"))]
ext if BGZF.contains(&ext) => Some(Self::Bgzf),
ext if BGZF.contains(&ext) => Ok(Self::Bgzf),

_ => None,
_ => Err(Error::new(
ErrorKind::InvalidInput,
format!("Unknown format '{}'", ext),
)),
}
}

pub fn from_path(path: impl AsRef<Path>, uncompressed_exts: &[&str]) -> Option<Self> {
let path = path.as_ref().extension()?.to_str()?;
pub fn from_path(path: impl AsRef<Path>, uncompressed_exts: &[&str]) -> Result<Self> {
let path = path
.as_ref()
.extension()
.and_then(|ext| ext.to_str())
.unwrap_or("");
Self::from_extension(path, uncompressed_exts)
}

Expand Down Expand Up @@ -81,25 +92,25 @@ mod tests {

// Uncompressed extensions
assert_eq!(
Format::from_extension("txt", uncompressed_exts),
Some(Format::Uncompressed)
Format::from_extension("txt", uncompressed_exts).unwrap(),
Format::Uncompressed
);

// Known compressed extensions
#[cfg(feature = "decode-gzip")]
assert_eq!(
Format::from_extension("gz", uncompressed_exts),
Some(Format::Gzip)
Format::from_extension("gz", uncompressed_exts).unwrap(),
Format::Gzip
);

#[cfg(feature = "decode-bgzf")]
assert_eq!(
Format::from_extension("bgzf", uncompressed_exts),
Some(Format::Bgzf)
Format::from_extension("bgzf", uncompressed_exts).unwrap(),
Format::Bgzf
);

// Unknown or empty extensions
assert_eq!(Format::from_extension("unknown", uncompressed_exts), None);
assert_eq!(Format::from_extension("", uncompressed_exts), None);
assert!(Format::from_extension("unknown", uncompressed_exts).is_err());
assert!(Format::from_extension("", uncompressed_exts).is_err());
}
}
9 changes: 5 additions & 4 deletions workspace/compress/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! compress data into a memory buffer, and then decompress it back to verify integrity.
//!
//! ```rust
//! use compress::{adapter::BoxedSync, decode::DecodeReadIntoRead, encode::Encode, Format};
//! use substratum_compress::{adapter::BoxedSync, decode::DecodeReadIntoRead, encode::Encode, Format};
//! use std::io::{Read, Write};
//!
//! fn main() -> std::io::Result<()> {
Expand All @@ -19,9 +19,8 @@
//! // 1. Setup & Inference
//! // ----------------------------------------------------------------------
//! // Detect format from extension (e.g., "gz" -> Format::Gzip)
//! let format = Format::from_extension("gz", &[]);
//! assert_eq!(format, Some(Format::Gzip), "Should infer Gzip format");
//! let format = format.unwrap();
//! let format = Format::from_extension("gz", &[]).unwrap();
//! assert_eq!(format, Format::Gzip, "Should infer Gzip format");
//!
//! // ----------------------------------------------------------------------
//! // 2. Encode (Write)
Expand Down Expand Up @@ -71,4 +70,6 @@ pub mod decode;
pub mod encode;
mod format;

pub use decode::Decoder;
pub use encode::Encoder;
pub use format::Format;