support snappy format

This commit is contained in:
figsoda 2021-12-07 13:59:56 -05:00
parent bafc2d31b4
commit 52a8acf2e1
8 changed files with 34 additions and 12 deletions

7
Cargo.lock generated
View File

@ -454,6 +454,7 @@ dependencies = [
"parse-display",
"proptest",
"rand",
"snap",
"tar",
"tempfile",
"test-strategy",
@ -713,6 +714,12 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "snap"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45456094d1983e2ee2a18fdfebce3189fa451699d0502cb8e3b49dba5ba41451"
[[package]]
name = "strsim"
version = "0.10.0"

View File

@ -22,6 +22,7 @@ libc = "0.2.103"
linked-hash-map = "0.5.4"
lzzzz = "0.8.0"
once_cell = "1.8.0"
snap = "1.0.5"
tar = "0.4.37"
walkdir = "2.3.2"
xz2 = "0.1.6"

View File

@ -72,11 +72,11 @@ ouch c file.txt file.zip
# Supported formats
| Format | `.tar` | `.zip` | `.bz`, `.bz2` | `.gz` | `.lz4` | `.xz`, `.lzma` | `.zst` |
|:---------:|:------:|:------:|:-------------:|:-----:|:------:|:---------------------:|:------:|
| Supported | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Format | `.tar` | `.zip` | `.bz`, `.bz2` | `.gz` | `.lz4` | `.xz`, `.lzma` | `.sz` | `.zst` |
|:---------:|:------:|:------:|:-------------:|:-----:|:------:|:--------------:|:-----:|:-------|
| Supported | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
And the aliases: `tgz`, `tbz`, `tbz2`, `tlz4`, `txz`, `tlz`, `tlzma`, `tzst`.
And the aliases: `tgz`, `tbz`, `tbz2`, `tlz4`, `txz`, `tlzma`, `tsz`, `tzst`.
Formats can be chained:

View File

@ -304,6 +304,7 @@ fn compress_files(files: Vec<PathBuf>, formats: Vec<Extension>, output_file: fs:
Bzip => Box::new(bzip2::write::BzEncoder::new(encoder, Default::default())),
Lz4 => Box::new(lzzzz::lz4f::WriteCompressor::new(encoder, Default::default())?),
Lzma => Box::new(xz2::write::XzEncoder::new(encoder, 6)),
Snappy => Box::new(snap::write::FrameEncoder::new(encoder)),
Zstd => {
let zstd_encoder = zstd::stream::write::Encoder::new(encoder, Default::default());
// Safety:
@ -321,7 +322,7 @@ fn compress_files(files: Vec<PathBuf>, formats: Vec<Extension>, output_file: fs:
}
match formats[0].compression_formats[0] {
Gzip | Bzip | Lz4 | Lzma | Zstd => {
Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => {
let _progress = Progress::new_accessible_aware(
total_input_size,
precise,
@ -454,6 +455,7 @@ fn decompress_file(
Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)),
Lz4 => Box::new(lzzzz::lz4f::ReadDecompressor::new(decoder)?),
Lzma => Box::new(xz2::read::XzDecoder::new(decoder)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),
Zstd => Box::new(zstd::stream::Decoder::new(decoder)?),
Tar | Zip => unreachable!(),
};
@ -466,7 +468,7 @@ fn decompress_file(
let files_unpacked;
match formats[0].compression_formats[0] {
Gzip | Bzip | Lz4 | Lzma | Zstd => {
Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => {
reader = chain_reader_decoder(&formats[0].compression_formats[0], reader)?;
let writer = utils::create_or_ask_overwrite(&output_file_path, question_policy)?;
@ -580,6 +582,7 @@ fn list_archive_contents(
Bzip => Box::new(bzip2::read::BzDecoder::new(decoder)),
Lz4 => Box::new(lzzzz::lz4f::ReadDecompressor::new(decoder)?),
Lzma => Box::new(xz2::read::XzDecoder::new(decoder)),
Snappy => Box::new(snap::read::FrameDecoder::new(decoder)),
Zstd => Box::new(zstd::stream::Decoder::new(decoder)?),
Tar | Zip => unreachable!(),
};
@ -604,7 +607,7 @@ fn list_archive_contents(
crate::archive::zip::list_archive(zip_archive)?
}
Gzip | Bzip | Lz4 | Lzma | Zstd => {
Gzip | Bzip | Lz4 | Lzma | Snappy | Zstd => {
panic!("Not an archive! This should never happen, if it does, something is wrong with `CompressionFormat::is_archive()`. Please report this error!");
}
};

View File

@ -57,7 +57,9 @@ pub enum CompressionFormat {
Lz4,
/// .xz .lzma
Lzma,
/// tar, tgz, tbz, tbz2, txz, tlz, tlz4, tlzma, tzst
/// .sz
Snappy,
/// tar, tgz, tbz, tbz2, txz, tlz4, tlzma, tsz, tzst
Tar,
/// .zst
Zstd,
@ -75,6 +77,7 @@ impl CompressionFormat {
Bzip => false,
Lz4 => false,
Lzma => false,
Snappy => false,
Zstd => false,
}
}
@ -91,6 +94,7 @@ impl fmt::Display for CompressionFormat {
Zstd => ".zst",
Lz4 => ".lz4",
Lzma => ".lz",
Snappy => ".sz",
Tar => ".tar",
Zip => ".zip",
}
@ -121,13 +125,15 @@ pub fn separate_known_extensions_from_name(mut path: &Path) -> (&Path, Vec<Exten
"tgz" => &[Tar, Gzip],
"tbz" | "tbz2" => &[Tar, Bzip],
"tlz4" => &[Tar, Lz4],
"txz" | "tlz" | "tlzma" => &[Tar, Lzma],
"txz" | "tlzma" => &[Tar, Lzma],
"tsz" => &[Tar, Snappy],
"tzst" => &[Tar, Zstd],
"zip" => &[Zip],
"bz" | "bz2" => &[Bzip],
"gz" => &[Gzip],
"lz4" => &[Lz4],
"xz" | "lzma" => &[Lzma],
"sz" => &[Snappy],
"zst" => &[Zstd],
_ => break,
};

View File

@ -83,6 +83,9 @@ pub fn try_infer_extension(path: &Path) -> Option<Extension> {
fn is_lz4(buf: &[u8]) -> bool {
buf.starts_with(&[0x04, 0x22, 0x4D, 0x18])
}
fn is_sz(buf: &[u8]) -> bool {
buf.starts_with(&[0xFF, 0x06, 0x00, 0x00, 0x73, 0x4E, 0x61, 0x50, 0x70, 0x59])
}
fn is_zst(buf: &[u8]) -> bool {
buf.starts_with(&[0x28, 0xB5, 0x2F, 0xFD])
}
@ -113,6 +116,8 @@ pub fn try_infer_extension(path: &Path) -> Option<Extension> {
Some(Extension::new(&[Lzma], "xz"))
} else if is_lz4(&buf) {
Some(Extension::new(&[Lz4], "lz4"))
} else if is_sz(&buf) {
Some(Extension::new(&[Snappy], "sz"))
} else if is_zst(&buf) {
Some(Extension::new(&[Zstd], "zst"))
} else {

View File

@ -20,8 +20,8 @@ enum DirectoryExtension {
Tbz,
Tgz,
Tlz4,
Tlz,
Tlzma,
Tsz,
Txz,
Zip,
}
@ -35,6 +35,7 @@ enum FileExtension {
Gz,
Lz4,
Lzma,
Sz,
Xz,
}

View File

@ -17,7 +17,7 @@ fn sanity_check_through_mime() {
write_random_content(test_file, &mut SmallRng::from_entropy());
let formats = [
"tar", "zip", "tar.gz", "tgz", "tbz", "tbz2", "txz", "tlz", "tlzma", "tzst", "tar.bz", "tar.bz2", "tar.lzma",
"tar", "zip", "tar.gz", "tgz", "tbz", "tbz2", "txz", "tlzma", "tzst", "tar.bz", "tar.bz2", "tar.lzma",
"tar.xz", "tar.zst",
];
@ -30,7 +30,6 @@ fn sanity_check_through_mime() {
"application/x-bzip2",
"application/x-xz",
"application/x-xz",
"application/x-xz",
"application/zstd",
"application/x-bzip2",
"application/x-bzip2",