You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
36 lines
1.2 KiB
Rust
36 lines
1.2 KiB
Rust
use crate::format::{FileFormat, FileObject};
|
|
use anyhow::{bail, Context};
|
|
use libflate::gzip::Decoder;
|
|
use std::fs::File;
|
|
use std::io;
|
|
use std::io::BufReader;
|
|
use std::path::Path;
|
|
|
|
pub const GZIP_HEADER: &[u8] = &[0x1f, 0x8b];
|
|
|
|
pub struct GZipFormat;
|
|
|
|
impl FileFormat for GZipFormat {
|
|
fn parse(file: &FileObject) -> anyhow::Result<Self> {
|
|
if file.header.starts_with(GZIP_HEADER) {
|
|
if !file.ext.ends_with(".gz") && !file.ext.ends_with(".gzip") {
|
|
tracing::error!("The file has a valid gzip signature but not a gzip extension");
|
|
}
|
|
Ok(Self)
|
|
} else {
|
|
bail!("Not a gzip file")
|
|
}
|
|
}
|
|
|
|
fn extract(&self, file: &Path, output: &Path) -> anyhow::Result<()> {
|
|
let mut reader = BufReader::new(File::open(file).context("Opening input")?);
|
|
let mut decoder = Decoder::new(&mut reader).context("Creating decoder")?;
|
|
let mut output_file =
|
|
File::create(output).with_context(|| format!("Creating output file {output:?}"))?;
|
|
tracing::debug!("Extracting to {output:?}");
|
|
io::copy(&mut decoder, &mut output_file).context("Deompressing file to output")?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|